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

先放一段代码,通过修改参数来理解以下四个问题:
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
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值