Java 覆写
继承性的主要特征是子类可以根据父类已有的功能进行功能扩展,但是在子类定义属性或方法的时候有可能定义属性和方法和父类同名,在此类情况下就称为:“覆写”。
方法的覆写:【改良原本功能不足的方法】
子类定义的方法与父类方法名称相同、参数的类型及个数、返回值相同的方法。
class A { public void fun() { System.out.println("A.fun()方法") ; } } class B extends A { public void fun() { System.out.println("B.fun()方法") ; } } public class TestAB { public static void main(String args[]) { B b = new B() ; b.fun() ; } }
当发生覆写之后,此时会调用实例化子类中被覆写的方法;{注意:覆写的方法,要和父类的一模一样才可以称为覆写操作}
一个类可能会产生(被继承)多个子类,那么每个子类都会有一个自己的代码方法,子类被实例化后只会执行自己被覆写的方法。【没有被覆写的方法,则调用父类的方法】
但是被覆写的方法不能拥有比父类更严格的访问控制权限
访问控制权限: Public > default > private(最严格的)
同理:如果父类使用了public,子类的覆写方法只能是public;如果父类使用了default,子类的覆写方法只能是public和default ……
class A { public void fun() { print() ; } public void print() { System.out.println("A") ; } } class B extends A { public void print() { System.out.println("B") ; } } public class TestAB { public static void main(String args[]) { B b = new B() ; b.fun() ; } }
说明:实例化子类B,所以fun方法是在B类中执行的,调用的就是B类中的print方法;
class A { public void fun() { print() ; } private void print() { System.out.println("A") ; } } class B extends A { public void print() { System.out.println("B") ; } } public class TestAB { public static void main(String args[]) { B b = new B() ; b.fun() ; } }
说明:这个例子中,就会发现子类中根本没有覆写print()方法,也就是说使用了private对于子类而言是不可见的,就算子类定义一个符合要求的覆写语句,也不可以发生覆写;这个时候子类使用的方法,实际上就相当于子类自己定义了一个新的方法而已。
覆写之后,默认情况下子类所能够调用的一定是被覆写过的方法,如果还想调用父类中的方法,可以使用super.* 关键字;
class A { public void fun() { print() ; } public void print() { System.out.println("A") ; } } class B extends A { public void print() { super.print() ; System.out.println("B") ; } } public class TestAB { public static void main(String args[]) { B b = new B() ; b.fun() ; } }
super()和this()问题研究:
1、 super(参数):调用基类(父类)中的某一个构造函数(默认)
2、 this(参数):调用本类中的另一种形成的构造函数
3、 super()和this()都在构造函数第一行,但不可以同时存在
4、 super:引用当前对象的直接父类的成员(用来访问父类中的隐式继承属性和方法函数)
5、 this:表示引用当前对象名,调用的只是本类中的属性和方法函数
— this()和super()都要在构造函数的首行。
面试题:解释重载与覆写的区别?(Overloading与Overrid的区别)
区别 |
重载 |
覆写 |
名字 |
Overloading |
Overrid |
范围 |
发生在一个类中 |
发生在子类和父类之中 |
定义 |
方法名称、参数类型及个数相同 |
方法名称、参数类型、个数、方法返回值相同 |
权限 |
没有权限的限制 |
被覆写的方法不能拥有比父类严格的访问控制权限 |
在Overloading时,返回值类型是否可以不同?
在发生重载的时候,返回值类型可以不同,但是考虑到程序设计的统一性,重载时,尽量保证返回值类型相同。
属性覆盖:【无意义】
如果子类定义了和父类完全相同的属性名称的时候,就称为属性的覆盖。
class A { String info = "Hello" ; } class B extends A { int info = 100 ; public void print() { System.out.println(this.info) ; //查找本类中的info System.out.println(super.info); //查找父类的info } } public class TestAB { public static void main(String args[]) { B b = new B() ; b.print() ; } }
·发生继承关系后,就会应用覆写操作,覆写的应用主要以 方法覆写 为主;
·如果子类需要使用父类指定的方法,但是发现父类的方法不能满足功能需求,就可以利用覆写方法,来完善父类方法的功能的同时保留父类的方法不被改变。
·被子类覆写的方法不能拥有比父类更为严格的访问控制权限。