5.1.3 动态绑定

(1)编译器查看方法名。

(2)编译器查看方法类型。

(3)找更合适的方法。包含方法与参数,与当前位置更接近的方法,如有f(int)和f(double),参数用int,则自动选择int;子类和父类都有同名方法,如果子类有,则优先选用子类方法。

(4)编译错误的情况:多匹配和零匹配

示例代码:

public class Main {

public static void main(String[] args){

Main solution = new Main();

//找到多个匹配

solution.f((short)5);

//找到零个匹配

solution.k();

}



public void f(Integer a){

System.out.println("int");

}



public void f(Double a){

System.out.println("double");

}

}

OTHER: JDK1.5以前要求返回类型子类父类一致,现在返回类型子类需要是父类中返回类型的子类

ASon是A类型的子类,所以运行下述代码不会产生错误:

示例代码:

public class Main {

public static void main(String[] args){

Main solution = new Main();

solution.new B().getA();

solution.new BSon().getA();

}



class A{

public A(){

System.out.println("create A");

}

}



class ASon extends A{

public ASon(){

System.out.println("create ASon");

}

}



class B{

public A getA(){

return new A();

}

}



class BSon extends B{

public ASon getA(){

return new ASon();

}

}

}

(3) private static final 方法或构造器,编译器可以准确的直到调用哪个方法,这叫动态绑定

调用方法依赖于隐式参数实际类型,叫做静态绑定。相比于动态绑定,静态绑定无需查找过程,速度更快。

Private:私有,方法无法被继承,所以可以静态绑定;

Static:静态,可以使用子类隐藏,但不进行向上转型一定用子类方法,进行向上转型一定用父类方法,所以可以静态绑定;

final:最终,无法被重写,隐含private,可以静态绑定。

参考资料:https://cloud.tencent.com/developer/article/1121665

子类隐式调用父类解析过程:

(1)提取子类父类方法表

(2)搜索当前类中的方法,找不到的情况搜索父类方法

(3)找到方法,进行调用返回

动态绑定的优点:无需对现存代码修改,通过继承关系,可以完成对程序的复用与扩展。

5.1.4 final 关键字

用途:

  1. 使用final修饰的变量是常量,只能在赋值、初始化块、构造器三者中选择一处进行赋值。后续无法对值类型的值以及引用类型引用进行修改。
  2. 使用final修饰的方法不可重写
  3. 使用final修饰的类,它不可被继承。这意味着它所有方法都不能重写。

问:是否又必要对所有无需继承的方法和类都使用final?

答:不需要。早期Java中,对于短方法可以优化,这种做法比较有必要;即时编译器JIT出现后,可以自动对简短频繁的方法进行内联处理,所以无需刻意把所有子类定义final。

5.1.5 强制类型转换

基本类型,使用小括号进行强制转换,同样引用类型也可以使用强制转换,但是仅适用于原本就是此类的变量,否则会报错。

示例代码:

public class Main {

public static void main(String[] args){

Main solution = new Main();

A a = solution.new A();

ASon aSon = solution.new ASon();

A tmp = aSon;//自动转换

ASon tmp2 = (ASon) tmp;//强制转换

ASon tmp3 = (ASon) a;//报错

}



class A{

public A(){

System.out.println("create A");

}

}



class ASon extends A{

public ASon(){

System.out.println("create ASon");

}

}



class B{

public A getA(){

return new A();

}

}



class BSon extends B{

}

运行结果:

《Java 核心技术 卷1》 笔记 第五章 继承(2)_后端


 系列内容

《Java 核心技术 卷1》 笔记:第一章 Java程序设计概述

《Java 核心技术 卷1》 笔记:第二章 Java程序设计环境

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(1)

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(2)

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(3)

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(4)

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(5)

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(6)

《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(7)大数处理、数组、多维数组、控制台传参

《Java 核心技术 卷1》 笔记 第四章:类与对象

《Java 核心技术 卷1》 笔记 第四章:类与对象(2) GregorianCalendar 与 类的基本组成

《Java 核心技术 卷1》 笔记 第四章:类与对象(3) 构造器全局私有方法

《Java 核心技术 卷1》 笔记 第四章:类与对象(4) 静态字段+静态方法+工厂方法

《Java 核心技术 卷1》 笔记 第四章:类与对象(5) 形参与实参 构造器的默认值与默认构造

《Java 核心技术 卷1》 笔记 第四章:类与对象(6) 构造器调用与初始化块

《Java 核心技术 卷1》 笔记 第四章:类与对象(7) 注释、JavaDoc与类设计

《Java 核心技术 卷1》 笔记 第五章 继承

喜欢的话,点个赞吧~!平时做题,以及笔记内容将更新到公众号。

关注公众号,互相学习:钰娘娘知识汇总