零基础Java:第十一讲(对象实例化过程、多态)

453 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

对象实例化过程

  • 对象实例化过程

    • 简单类对象的实例化过程
    • 注:

      • 第三步开辟空间是给new Person();开辟
      • 第五步构造方法进栈,指的是public Person(){}进栈,初始化指的是执行构造方法的方法体中的代码。
      • 第六步将堆内存地址赋值给引用变量,即赋值给P,P存储堆中的地址
    • 子类对象实例化过程
    • 注:

      • 第一步是先加载父类再加载子类
      • 第三步开辟空间是给new Student();开辟
      • 第四步对象空间即开辟的堆内存空间,默认初始化age=0,name=null,sex=0,school=null.(父类子类属性均初始化)
      • 第五步子类构造方法进栈,但构造方法中又super,所以转去执行第六步显示初始化父类的属性,此时age=1,name=“zhangsan”,sex=0
      • 第七步public Person(){}执行完成出栈
      • 第八步显示初始化子类属性,school仍然为null
      • 第九步stu存储BE3500地址

面向对象特征之三:多态

  • 面向对象特征之三:多态

    • 多态性,是面向对象中最重要的概念,在java中有两种体现:

      • 方法的重载(overload)【本类中的同名方法——体现相同的名称方法实现不同的逻辑】和重写(overwrite)【子类对父类方法的覆盖——体现子类可以使用和父类相同的方法名,覆盖掉父类的逻辑。父类的方法想要修改,但有别的代码在调用父类的方法,可以考虑子类继承父类,重写父类的方法】
      • 对象的多态性——可以直接应用在抽象类和接口上
    • Java引用变量有两个类型:编译时类型和运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定

      • 例如:Student stu=new Student();其中Student stu为编译时类型,new Student()为运行时类型
      • 若编译时类型和运行时类型不一致,就出现对象的多态(Polymorphism)
    • 对象的多态——在java中,子类的对象可以替代父类的对象使用

      • 一个变量只能由一种确定的数据类型
      • 一个引用类型变量可能指向(引用)多种不同类型的对象
      • 举例 :Person p=new Person(); Person e=new Student();//Person类型的变量e,指向Student类型的对象
    • 可以这样操作的原因:子类可看做是特殊的父类(可以看成父类的扩展),所以父类类型的引用可以指向子类的对象:向上转型(upcasting)【把子类的对象可以给父类的类型变量引用】
    • 注意:一个引用类型的变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法
    • 虚拟方法的调用(Virtual Method Invocation)

      • 正常的方法调用
      • 虚拟方法调用(多态情况下)
      • 编译时类型和运行时类型

        • 编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。——动态绑定
      • 引用变量引用(P)那个对象,就使用该对象的方法
    • 多态小结

      • 前提

        • 需要存在继承或者实现关系
        • 要有覆盖操作(overload、overwrite)
      • 成员方法

        • 编译时:要查看引用变量所属的类中是否有所调用的方法
        • 运行时:调用实际对象所属的类中的重写方法
        • 注:成员方法的多态性,也就是动态绑定,必须得存在于方法的重写之上
      • 成员变量(属性):

        • 不具备多态性,只看引用变量所属的类
      • 子类继承父类

        • 如果子类没有重写父类的方法,那么子类就是直接使用父类的方法;如果重写了,子类就使用自己重写之后的方法
        • 子类定义了和父类完全相同的实例变量,这个实例变量不会覆盖父类中定义的实例变量。例如:父类定义int age;子类也定义int age;不会覆盖
    • 多态性应用举例

      • 方法声明形参类型为父类类型,可以使用子类的对象作为实参调用方法
    • instanceof操作符

      • x instanceof A:检验x是否为A类的对象,返回值为boolean型

        • 要求x所属的类与类A必须是子类和父类的关系,否则编译错误
        • 如果x属于类A的子类B,x instanceof A值也为true