java动态绑定机制,继承

提示:一段简单的代码,了解回顾java的动态绑定机制和继承


一、继承

注意

  • 类只允许单继承,不允许多继承,支持多重继承
  • java.lang.Object 类是 Java 语言的根类,任何类都是 Object 类的子类 / 间接子类

子类可以访问的父类成员

  • 可访问
    public 或 protected 修饰的成员
    同包中缺省访问权限修饰符的成员
  • 不可以直接访问
    不同包中缺省访问权限修饰符的成员
    private 修饰成员

继承的细节

1、子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问

2 、子类必须调用父类的构造器, 完成父类的初始化

3 、当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无 参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译报错。

4、 如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)

5 、super() 在使用时,必须放在构造器第一行

6 、super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器

7 、java 所有类都是 Object 类的子类, Object 是所有类的基类.

8、 父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(顶级父类)

9、 子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制。
思考:如何让 A 类继承 B 类和 C 类? 【A 继承 B, B 继承 C】

10、 不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系

二、动态绑定机制

1、动态绑定是指在执行期间(非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。程序运行过程中,把函数(或过程)调用与响应调用所需要的代码相结合的过程称为动态绑定。
(编译阶段是确保方法的存在性,保证程序能顺利、安全运行。)

2、可以理解为:在程序运行过程中,根据具体的实例对象去具体确定是哪个方法。

3、方法看运行,属性看编译。

4、向上转型时,用父类引用执行子类对象,并可以用父类引用调用子类中重写了的同名方法。但是不能调用子类中新增的方法。

三、代码示例分析

/**
 * @Author HYL
 * @Date 2022/8/20 9:57
 * @Version 1.0
 */
class Base{
    int i;
    Base(){
            add(1);
            System.out.println(i);
    }
    void add(int v){
            i+=v;
            System.out.println(i);
    }
}
class MyBase extends Base{
    MyBase(){
        System.out.println("MyBase");
        add(2);
    }
    @Override
    void add(int v){
        System.out.println("MyBase Add");
        i+=v*2;
        System.out.println(i);
    }
}
public class test01 extends MyBase {
    public static void main(String[] args) {
//        go(new MyBase());
        MyBase base=new test01();
        go(base);

    }
    static void go(Base b){
        b.add(8);
    }
}

运行结果:
在这里插入图片描述
分析:

MyBase base :编译类型
new test01() :运行类型
MyBase base=new test01(); //向上转型,父类引用指向子类对象。
对象的创建过程:

  • 1、加载类信息,只加载一次。
  • 2、在堆中分配空间(地址)。
  • 3、完成对象的初始化:
    1) 默认初始化(赋初值 0,null)
    2)显示初始化(变量定义时的赋值)
    3)构造器的初始化
  • 4、返回对象在堆中的地址给引用。
    在继承中:子类必须调用父类的构造器, 完成父类的初始化 。
    (1)、所以在new test01();执行时,会先隐式调用其直接父类MyBase的无参构造器,而MyBase又继承了Base,Base又继承了Object,所以在构造方法执行时(Object——>Base——>MyBase——>test01)。
    (2)、在执行Base的无参构造时,调用add(1)方法,而其子类重写了add()方法,由动态绑定机制,会调用子类MyBase的add方法:先输出 MyBase Add ;在运算i+=v2;在输出i的值,i=2;add(1)执行完了,再继续执行输出语句,此时i的值已改变,输出i=2
    (3)、在执行MyBase的无参构造:输出MyBase;在执行add(2),执行自己的add方法,输出MyBase Add,再计算i+=v
    2,此时的i在步骤(2)中已经变为了2,所以计算后i=6,打印输出
    (4)、最后轮到test01执行自己的无参构造方法。
    (5)、执行完构造方法,执行go(base),仍由于动态绑定机制,执行的是MyBase的add方法。先输出MyBase Add;在计算i+=v*2,此时的i在步骤三中已经变为了6,所以计算出i=22,打印输出
package cn.hyl.login.test;

/**
 * @Author HYL
 * @Date 2022/8/20 9:57
 * @Version 1.0
 */
class Base{
    int i;
    Base(){
            add(1);
            System.out.println(i);
    }
    void add(int v){
            i+=v;
            System.out.println(i);
    }
}
class MyBase extends Base{
    MyBase(){
        System.out.println("MyBase");
        add(2);
    }
    /*
    @Override
    void add(int v){
        System.out.println("MyBase Add");
        i+=v*2;
        System.out.println(i);
    }
    */
}
public class test01 extends MyBase {
    public static void main(String[] args) {
//        go(new MyBase());
        MyBase base=new test01();
        go(base);

    }
    static void go(Base b){
        b.add(8);
    }
}

运行结果:
在这里插入图片描述

分析:
在MyBase注释了add方法后:
(1)、所以在new test01();执行时,会先隐式调用其直接父类MyBase的无参构造器,而MyBase又继承了Base,Base又继承了Object,所以在构造方法执行时(Object——>Base——>MyBase——>test01)。
(2)、在执行Base的无参构造时,调用add(1)方法,由动态绑定机制,会调用父类Base的add方法:先i+=v;在输出i的值,i=1;add(1)执行完了,再继续执行输出语句,此时i的值已改变,输出i=1
(3)、在执行MyBase的无参构造:输出MyBase;在执行add(2),(继承机制)执行父类的add方法,先计算i+=v,此时的i在步骤(2)中已经变为了1,所以计算后i=3,打印输出
(4)、最后轮到test01执行自己的无参构造方法。
(5)、执行完构造方法,执行go(base),执行add(8)仍由于动态绑定机制,执行的是父类的父类(多重继承)Base的add方法。先计算i+=v,此时的i在步骤三中已经变为了2,所以计算出i=11,打印输出

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值