Java笔记(八)重写(覆盖Override)、重载、封装、访问控制符、接口

public class bird {
	//bird类的fly方法
	public void fly(){
		System.out.println("我会飞...");
	}
}
public class Try01 extends bird{
	//重写bird类的fly方法
	public void fly(){
		System.out.println("我只能在地上跑...");
	}
	public void callOverrideMethod(){
		//在子类方法中通过super来显式的调用父类被覆盖的方法
		super.fly();
	}
	public static void main(String[] args) {	
		//创建Ostrich对象
		Try01 os =new Try01();
		//执行Ostrich对象的fly方法,将输出“我只能在地上跑...”
		os.fly();
		os.callOverrideMethod();
	}


	}

        这种子类包含与父类同名方法的现象被称为方法重写,也被称为方法覆盖(Override)。可以说子类重写了父类的方法,也可以说子类覆盖了父类的方法。Java方法的重写要遵循“两同两小一大”规则,“两同”是指方法名相同、形参列表相同;“两小”是指子类方法返回值类型应比父类方法返回值类型更小或相等,子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等;“一大”是指之类方法的访问权限应比父类方法更大或相等(父类中的方法并不是在任何情况下都可以重写的,但父类的方法控制修饰符为private时,该方法只能被自己的类访问,不能被外部的类访问,在子类是不能被重写的;如果定义父类的方法为public,在子类中绝对不能定义为private)。还有特别需要注意的是:覆盖方法和被覆盖方法要么都是类方法,要么都是实例方法,不能一个是类方法,一个是实例方法

        重写方法的两个注意事项:(1)当子类覆盖了父类方法后,子类对象将无法访问父类中被覆盖的方法,但还可以在子类方法中调用父类中被覆盖的方法。如果需要在子类方法中调用父类中被覆盖的方法,可以使用super(被覆盖的是实例方法)或者父类类名(被覆盖方法是类方法)作为调用者来调用父类中被覆盖的方法。(2)如果父类方法具有私有(private)访问权限,则该方法对其子类是隐藏的,其子类无法访问该方法,也就是说无法重写该方法。如果在子类中定义了一个与父类private方法具有相同名字的方法,相同形参列表,相同返回值类型的方法,依旧还不是重写,只是在子类中重新定义了一个新方法。

        同一类中可以有两个或者多个方法具有相同的方法名,只要他们的形参列表不同即可,这就是方法的重载。Java中的重载规则十分简单,参数决定了重载方法的调用

        “继承可重写,方法可重载”

        封装是面向对象的三大特征("封装、"多态"、"继承")之一,是指将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。借助于访问控制符实现封装,把该隐藏的隐藏起来,把该暴露的暴露出来。

        四个访问控制符:

        private:如果类里的一个成员(包括属性和方法)使用private访问控制修饰时,这个成员只能在该类的内部被访问。显然,private用于修饰属性最合适,可以把属性隐藏在类的内部

        default:如果类里的一个成员(包括属性和方法)或者一个顶级类不使用任何访问控制符修饰,则称它是默认访问控制,default访问控制的成员或顶级类可以被相同包下的其他类访问

        protected:如果类里的一个成员(包括属性和方法)使用protected访问控制修饰,那么这个成员既可以被同一个包中的其他类访问,也可以被不同包中的子类访问。在通常情况下,如果使用protected来修饰一个方法,通常是希望其子类来重写这个方法

        public:这是一个最宽松的访问控制级别,如果类里的一个成员(包括属性和方法)或者一个顶级类使用了public修饰,这个成员或顶级类可以被所有类访问,不管访问类和被访问类是否处于同一个包中,是否具有父子继承关系。 

interface jiekou1 {//接口中只能声明常量
	public int a=100;
	static int b=200;
	final  int c=300;
}
interface jiekou2{//接口中的方法都是抽象的或公共的
	int add(int a,int b);
	void print0();
}
interface jiekou3 extends jiekou1,jiekou2{//接口的继承
	
	abstract public void print1();
}
class shixian implements jiekou1,jiekou2,jiekou3{
	//实现接口,重写方法
	public int add(int a ,int b){
		return a+b;
	}
	
	public void print0(){
		System.out.println("jiekou2接口里第一和第二个方法没有修饰符");
	}

	public void print1() {
		
		System.out.println("jiekou3接口里第一个方法有修饰符abstract和public");
	}


}
public class Try01 {

	public static void main(String[] args) {	
		//初始化实例对象
		shixian aa=new shixian();
		//接口的引用执行对象的引用
		jiekou3 bb=aa;
		
		System.out.println("a+b="+aa.add(100,200 ));
		//对象引用并调用方法
		aa.print0();
		bb.print1();
		System.out.println("a="+jiekou3.a+" b="+jiekou3.b);
		
	}


	}

        定义接口的方法和定义类的方法十分相似,并且在接口里面也有方法,在接口中可以派生出新的类。一旦创建接口,接口的方法是抽象的,也就是说接口不具备实现的功能,他只是指定要做什么,而不管具体怎么做。一旦定义了接口,任何类都可以实现这个接口,他与类不同,一个类只可以继承一个类,但是一个类可以实现多个接口,解决了一个类要具备多方面的特征的问题。接口的修饰符只能是public,因为只有这样接口才能被任何包中的接口或类访问。在接口中不能声明变量,因为接口要具备3个特征,即公共性、静态和最终的,声明的常量可以用public、static和final修饰。接口里的方法都是抽象的或者公有的,在方法声明的时候,可以省略关键字public、static,因为他的方法都是公有和抽象的,不需要关键字修饰,当然加上也没有错。在接口的实现过程中,一是能为所有的接口提供实现的功能,二是遵循重写的所有规则,三是能保持相同的返回的数据类型。在编写的程序时,用户可以建立接口类型的引用变量。接口的引用变量能够存储一个指向对象的引用值,这个对象可以实现任何该接口的类的实例,用户可以通过接口调用该对象的方法,这些方法在类中必须是抽象方法。接口的继承和类的继承不一样,接口完全支持多继承,即一个接口可以有多个直接父接口。和类继承相似,子接口扩展某个父接口,将会获得接口里定义的所有抽象方法、常量属性、内部类和枚举类定义。

        接口和抽象类的相同之处:都不能被实例化,都位于继承树的顶端,用于被其他类实现和继承;都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。接口和抽象类存在的差别:(1)接口里只能包含抽象方法,不包含已经提供实现的方法;抽象类则完全可以包含普通方法。(2)接口里不能定义静态方法,而抽象类里面可以定义静态方法。(3)接口里面只能定义静态常量属性,不能定义普通属性。抽象类里面则即可以定义普通属性也可以定义静态常量属性。(4)接口不包含构造器。抽象类里面可以包含构造器,抽象类里的构造器并不用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。(5)接口里面不能包含初始化块,但抽象类则完全可以包含初始化块。(6)一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承的不足。

猜你喜欢

转载自blog.csdn.net/steriles_/article/details/80435845