super 和 this 关键字的比较+调用构造器(this)+动态绑定

【0】README

0.1) 本文描述+源代码均 转自 core java volume 1, 旨在加深对 super 和 this关键字 的用法比较;
0.2) 最后还补充了 多态和动态绑定 的定义 以及对动态绑定进行了详细分析,这两个定义给的非常棒;


【1】super 和 this 的比较:

1.1) 有人认为super 和 this 引用是类似的概念,实际上,这样比较并不太恰当;因为super不是一个对象引用, 不能将super 赋给另一个对象变量,它只是一个编译器调用超类方法的特殊关键字;
1.2)我们再看super在构造器中的应用:

public Manager(String n, double s, int year, int month, int day)
{
super(n, s, year, month, day);
bonus = 0;
}
  • 这里的super含义是: super(n, s, year, month, day) 是“调用超类Employee中含有 n、s、year、month 和 day” 参数的构造器的简写形式;
  • 这是由于: Manager类的构造器不能访问 Employee类 的私有域, 所以必须利用 Employee类的构造器对这部分私有域 进行初始化;

Attention)

  • A1)而且 使用 super调用构造器的语句必须是 子类构造器的第一条语句;
  • A2)如果子类的构造器没有显式地 调用超类的构造器,则将自动地调用超类默认构造器;

Annotation)关键字this + super 有两个用途:

  • A1)this的用途:一是引用隐式参数+二是调用该类其它的构造器;
  • A2)super的用途:一是调用超类 的方法 + 而是调用超类都构造器;

【2】调用构造器

2.1)调用构造器的注意事项 : 调用构造器的语句只能作为 另一个构造器的第一条语句出现, 构造参数既可以传递给本类的其他构造器, 也可以传递给超类的构造器;

2.2)看个荔枝(利用this调用其他构造器):


2.3)Complementary

  • C1)多态: 一个对象变量可以指示多种实际类型的现象 被称为多态;(如上述代码中的 e 即可以指向 Manager类 也可以指向 Employee类)
  • C2)动态绑定:在运行时能够自动地选择调用哪个方法的现象称为动态绑定

【3】 动态绑定

3.1)定义: 在运行时能够自动地选择调用哪个方法的现象称为 动态绑定
如:

Manager boss = new Manager("tangrong", 80000, 1987, 12, 15):
staff[0] = boss;
staff[1] = new Employee("tangtang", 1, 2, 3, 4);
staff[2] = new Employee("rongrong", 4, 3, 2, 1);
for(Employee e: staff)
System.out.println(e.getName() + " " + e.getSalary() );
  • e.getSalary() 调用能够确定应该执行哪个 getSalary 方法, 请注意, 这里虽然将e 声明为 Employee 类型,但实际上 e 既可以引用Employee 类型的对象,也可以引用Manager 类型的对象;

3.2)看一下对象方法的执行过程,调用过程的详细描述(Description):

  • D1)编译器查看对象的声明类型和方法名:例如可能存在方法 f(int) 和 方法 f(String), 编译器将会一一列举所有C类中名为f的方法和其超类中访问属性为public 且名
    为f的方法;
  • D2)编译器将查看调用方法时提供的参数类型:
    重载解析:如果在所有名为f 的方法中存在一个与提供的参数类型完全匹配, 就选择这个方法,这个过程叫做重载解析;
  • D3)如果是private、static、final 方法或者构造器, 那么编译器将可以正确地知道应该调用哪个方法;我们将这种调用方式叫做静态绑定;与此对应的是,调用的方法依赖于隐式参数的实际
    类型,并且在运行时实现动态绑定;
  • D4)当程序运行, 并且采用动态绑定调用方法时, 虚拟机一定调用与x 所引用对象的实际类型最合适的那个类的方法;假设x 的实际类型为D, 它是C类的子类, 如果 D类定义了 方法f(string), 就直接调用它,否则将在D类的超类中寻找f(string), 以此类推;

3.3)方法表:每次调用方法都要进行搜索, 时间开销相当大, 因此虚拟机预先为每个类创建了一个方法表(method table), 其中列出了所有方法的签名和实际调用 的方法;
Annotation)

  • A1)方法签名:方法的名字和参数列表称为方法的签名; 如,f(int) 和 f(String) 是两个具有相同名字、不同签名的方法;如果在子类中定义了一个与超类签名相同的方法,那么子类中的这个方法就覆盖了超类中的这个相同签名的方法;
  • A2)返回类型不是方法签名的一部分:因此,在覆盖方法时, 一定要保证返回类型的兼容性;允许子类将覆盖方法的返回类型定义为原返回类型的子类型;
    如父类有: public Employee getBuddy(){}, 子类可以覆盖它, public Manager getBuddy(){} ;我们说,这两个 getBuddy 方法具有 可协变的返回类型

3.4)在运行的时候, 调用 e.getSalary() 的解析过程(Procedure):

  • P1)首先,虚拟机提取e 的实际类型的方法表: 既可能是Employee、Manager的方法表,也可能是 Employee 类的其他子类的方法表;
  • P2)接下来, 虚拟机搜索定义 getSalary 签名的类, 此时,虚拟机已经知道应该调用哪个方法;
  • P3)最后,虚拟机调用方法;

3.5)动态绑定有一个重要的特性:无需对现在的代码进行修改, 就可以对程序进行扩展。
Alert)在覆盖一个方法的时候, 子类方法不能低于超类方法的可见性;特别是, 如果超类方法是public, 子类方法一定要声明为public;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值