方法重写规则及理解

定义:在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。

规则
1.子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表
2.子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型
  (1)返回值是基本数据类型时,必须和父类的返回值类型相同
  (2)返回值是引用数据类型时(类类型),子类重写方法返回的类型应该是父类被重写方法返回的类型或者其子类。(小于等于)
3.子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限
  注意:子类不能重写父类中声明为private权限的方法
4.子类方法抛出的异常不能大于父类被重写方法的异常

注意
子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。

理解
1.子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表
答:确定性,如果不具备基本的方法名称和参数列表,就确定不了需要被重写方法的位置。

2.子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型
答:因为多态,我们将子类向上转型为父类后,调用父类重写的方法,得到返回值,因为java是个强类型语言,所以编译期间要给返回值赋予类型。因为,编译期间的返回值类型(父类的)需要大于等于运行时期的返回值类型(子类的)。

// 父类
class SuperClass{
	 public People create(){
		return new People();
	}
}
// 子类
class SubClass extends SuperClass{
	public Student create(){
		return new Student();
	}
}

class People{
}

class Student extends People{
}

public class OverrideTest {
	public static void main(String[] args) {
		SuperClass test = new SubClass();
		//多态性,return new D(),故返回类型应该小于等于编译时类型(C类,父类中被重写的返回值类型)
		People testC = test.create();
	}
}

3.子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限
答:因为在使用多态的时候经常把子类向上转型为父类,进而父类.方法(形参列表)。而“父类.方法(形参列表)”这个语句能够编译成功没有报错,说明该方法的权限修饰符是可以在调用该方法的语句块中执行的,所以如果子类的被重写的方法的权限修饰符是大于等于父类该方法的权限修饰符,那么多态时就一定可以调用子类重写的方法,也就是运行时权限修饰符要大于等于编译器权限修饰符,这样才能保证运行时满足权限。

// 父类
class SuperClass{
	public void method(){
	}
}
// 子类
class SubClass extends SuperClass{
	//非法,子类中的method()的访问权限private比被覆盖方法的访问权限public小
	private void method(){//error
	}
}


public class OverrideTest {
	public static void main(String[] args) {
		SuperClass a = new SubClass();
		a.method();//保证此时SubClass.method()是可以运行的
	}
}

4.子类方法抛出的异常不能大于父类被重写方法的异常
答:如果子类重写的方法抛出的异常更大,那么在多态的情况下, 父类的引用调用的方法只能看到小范围的异常,代码运行的时候,才知道具体是调用了那个子类对象的方法,如果此时子类对象的方法抛出的异常更大,从逻辑上来说,是错误的。

class A{//父类
	 public void method() throws IOException{
	}
}
class B extends A{//子类
	// 子类重写的方法抛出的异常类型小于等于父类被重写的方法抛出的异常类型
	public void method() throws FileNotFoundException{
	}
}


public class OverrideTest {
	public static void main(String[] args) {
		OverrideTest test = new OverrideTest();
		test.display(new B());
	}
	public void display(A a){
		try {
			a.method();
		} catch (IOException e) {  
            // SuperClass 抛出的异常是 IOException,处理 IOException 异常
			// 如果子类抛出的异常更大,那么 父类就无法 catch 子类的异常。
			// 所以禁止子类抛出的异常更大
			e.printStackTrace();
		}
	}
}

你可能感兴趣的:(Java学习笔记(尚硅谷),java)