基于Java代码对this,动态绑定,覆盖和隐藏的探讨和思考

来源:互联网 发布:C语言手写笔记图片 编辑:程序博客网 时间:2024/06/06 02:24

先放一段代码,通过修改参数来理解以下四个问题:
1.父类子类混合创建一个新对象的构造逻辑(多态性及动态绑定)
2.this.方法实质
3.静态方法的隐藏(成员变量)
4.非静态方法的覆盖
对1的解释:声明父类新建子类对象的与常规新建对象的区别(A p = new B()):
先看如下代码,A是B的父类,m()被覆盖。

class A {    int x=1;//被隐藏    A() {        System.out.println("这里构建了一个父类对象");    }    void m() {//被覆盖        System.out.println("这里是父类的实例方法m()");    }    void m1() {        this.m();        this.m2();        this.m3();        System.out.println(this.x);        System.out.println("这里是父类的实例方法m1()");    }    static void m2(){//被隐藏    System.out.println("这里是父类的静态方法m2()");}    void m3() {//未被覆盖        System.out.println("这里是父类的实例方法m3()");    }   }class B extends A {    int x=2;    B() {        System.out.println("这里构建了一个子类对象");    }    void m() {        System.out.println("这里是子类的实例方法m()");    }    static void m2(){    System.out.println("这里是父类的静态方法m2()");}}public class Test1 {    public static void main(String[] args) {        A a = new A();        a.m1();        System.out.println();        B b = new B();        b.m1();        System.out.println();        A c = new B();        c.m1();    }}

输出结果为:
这里构建了一个父类对象
这里是父类的实例方法m()
这里是父类的静态方法m2()
这里是父类的实例方法m3()
1
这里是父类的实例方法m1()

这里构建了一个父类对象
这里构建了一个子类对象
这里是子类的实例方法m()
这里是父类的静态方法m2()
这里是父类的实例方法m3()
1
这里是父类的实例方法m1()

这里构建了一个父类对象
这里构建了一个子类对象
这里是子类的实例方法m()
这里是父类的静态方法m2()
这里是父类的实例方法m3()
1
这里是父类的实例方法m1()

可以看出:
构造顺序为
父类属性初始化-》父类构造方法-》子类属性初始化-》子类构造方法
而且实际会构造的对象要看声明的类型,如果是子类就是子类的。
其中A c = new B();构建顺序为先构建父类,再构建子类。但只能调用被子类覆盖的方法,而不能调用子类独用的方法。(在B中设计一个父类没有的m3方法,然后用c.m3()调用,发现报错,m3()未被定义。哪怕m3()改为静态方法也不行)
也就是说只多了一个被覆盖的方法,其他没影响。

而且this指的就是this这个词自己所在的类,而非网上部分文章说的是建立的对象(new后面的)的类,只是被覆盖的方法除外,隐藏了没用。而且A中的this去掉也没有影响。

父类中被覆盖的方法在父类中无法调用,在子类中可以用super调用,其他地方可以通过只建立父类对象直接调用,用子类间接调用只能找子类里用的super方法的。

被隐藏的变量和静态方法可以在父类中被直接调用,其他和覆盖一致。

下面可以利用另一端代码进行练习测试:

class A{    int x = 1;//被隐藏    void print(){//被覆盖        System.out.println("这里是父类方法,x="+x);//父类A的方法中访问的变量必然是A类或A的父类的,不可能访问B类的。        m();//父类A的方法中调用的实例方法m()是子类B的,由于发生了覆盖    }    void m(){//被覆盖        System.out.println("这里是父类的实例方法m()");    }    static void m2(){//被隐藏        System.out.println("这里是父类的静态方法m2()");    }}class B extends A{    int x = 2;     void print(){        System.out.println("这里是子类方法,x="+x);//子类方法访问的变量是子类对象的(当然条件是子类中声明了这个变量)        System.out.println("这里是子类方法,super.x="+super.x);//super.x是父类对象的        super.print();//调用父类的print()方法        m();//调用本对象的m()方法    }    void m(){        System.out.println("这里是子类的实例方法m()");    }    static void m2(){        System.out.println("这里是子类的静态方法m2()");    }    static void m3(){//静态与否都没用        System.out.println("这里是子类的实例方法m3()");    }}public class Test{    public static void main(String []s){        A p = new B();        System.out.println(p.x);//通过引用变量p来访问变量或静态方法,要看p的声明类型。所以x是A类的。        p.m2();//同上。静态方法m2()是A类的。        p.print();//通过引用变量p来访问实例方法,要看p指向的对象的实际类型。由于覆盖,调用的print()方法是子类的。        p.m3();//报错The method m3() is undefined for the type A    }}
阅读全文
0 0
原创粉丝点击