深入理解java继承——java继承中容易犯的错误

来源:互联网 发布:淘宝店开了怎么上货 编辑:程序博客网 时间:2024/06/05 19:35

        java的继承问题是笔试面试中常考的热点之一,请看下面几个例子,并加以比较:

        在看例子之前,首先关于继承有以下几个原则:

       (1)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法
       (2)子类中定义的成员变量和父类中定义的成员变量相同时,则父类中的成员变量被隐藏
       (3)子类中定义的成员方法,并且这个成员方法的名字,返回类型,及参数个数和类型与父类的某个成员方法完全相同,则父类的成员方法被覆盖。

        Test1.java

        

package extend;class A1{int a = 1;public int getA() {return this.a;}}class B1 extends A1 {int a = 2;}public class Test1 {public static void main(String[] args) {B1 b =new B1();System.out.println(b.getA());}}

        此例中,B1继承了A1, 根据原则(2),父类中的int a 变量被隐藏,所以此时如果直接打印:b.a,得到的结果会是2。但是因为B1中没有同名的getA()方法,所以b.getA()中调用的getA()是继承自A1类的,A1类中的getA()调用的是它本身的a(A1.a),所以输出为: 1

      
        Test2.java

package extend;class A2{int a = 1;public int getA() {return this.a;}}class B2 extends A2 {int a = 2;public int getA() {return this.a;}}public class Test2 {public static void main(String[] args) {B2 b = new B2();System.out.println(b.getA());}}

        此例中与上个例子的不同之处在于,B2类中定义了同名的getA()方法覆盖了A2类中的同名方法,所以这里b.getA()调用的是B2类中的方法,又因为B2中的getA()方法引用的是B2类自身的变量a(B2.a),所以打印结果为: 2


        Test3.java

package extend;class A3 {int a = 1;public int getA() {return this.a;}}class B3 extends A3 {public B3() {a = 2;}}public class Test3 {public static void main(String[] args) {B3 b = new B3();System.out.println(b.getA());}}

        此例中,子类(B3)既继承了父类(A3)的变量a,同时也继承了父类的getA()方法,所以B3()中的构造函数对a的赋值实际上是对继承自父类的变量a的赋值。由于没有覆盖,b.getA()调用的也是继承自父类A3的方法。输出结果很显然应该是 : 2

         Test4.java

package extend;class A4 {int a = 1;public int getA() {return a;}}class B4 extends A4 {int a = 2;public B4() {a = 3;}}public class Test4 {public static void main(String[] args) {B4 b = new B4();System.out.println(b.getA());}}

        此例中,子类B4中重新定义了同名的变量a,根据规则(2),A4中的变量a被隐藏,所以B4的构造函数中初始化的是B4类中的a,而由于没有重写方法覆盖getA(),所以b.getA()调用的仍然是A4类(父类)中的getA()方法,父类的getA()中返回的a自然是父类本身的变量a,而父类本身的变量a从初始化后一直没变,就是1,所以打印结果是: 1

         顺便提一下:

        1. 如果调用父类方法,则父类方法中引用的变量一定是父类中的变量(如Test1.java)

        2.如果调用子类方法,那么:如果子类中没有重新定义父类中的某个变量(没有隐藏),而在子类方法中引用了,则引用的是父类的变量;如果在子类中重新定义了变量(实现了隐藏),则引用的是子类本身的变量



原创粉丝点击