方法调用绑定
将一个方法调用同一个方法主体关联起来被称作绑定。若在程序执行前进行绑定,叫做前期绑定。读者可能以前从来没有听说过这个术语,因为它是面向过程的语言中不需要选择就默认的绑定方式。
上面问题的解决办法就是后期绑定,它的含义就是在运行时根据对象的类型进行绑定。后期绑定也就做动态绑定或运行时绑定。如果一种语言想实现后期绑定,就必须具有某种机制,一遍在运行时能判断对象的类型,从而调用恰当的方法。也就是说,编译器一直不知道对象的类型,但是方法的调用机制能找到正确的方法体,并加以调用。后期绑定机制随编程语言的不同而有所不同,但是只要想一下就会得知,不管怎样都必须在对象中安置某种“类型信息”。
Java中除了static方法和final方法之外,其他所有的方法都是后期绑定。这意味着通常情况下,我们不必判定是否该进行后期绑定—它会自动发生。
final可以关闭动态绑定,但是性能不需要我们考虑,不要试图用final来提高系统的性能。
缺陷:“覆盖”私有方法
由于private方法被自动认为是final方法,而且对导出类是屏蔽的。因此,在这种情况下,Derived类中的f()方法就是一个全新的方法;既然基类中的private方法在子类中式不可见的,所以也就不会被重载。
缺陷:域与静态方法
当sub对象转型为Super引用时,任何域访问操作都将由编译器解析,因此不是多态的。
Sub.field Super.field各自调用各自的。
如果某个方法是静态的,它的行为就不具有多态性。
静态方法是与类,而并非与单个的对象相关联的。
构造器和多态
通常,构造器不同于其他种类的方法。涉及到多态时仍是如此。尽管构造器并不具有多态性(
它实际上是static方法,只不过该static声明是隐式的),但还是非常有必要理解构造器怎么通过多态在复杂的层次结构中运作。
构造器的调用顺序
1)调用基类构造器。这个步骤会不断地反复递归下去,首先是构造这种层次结构的根,然后是下一层导出类,等等,直到最底层的导出类。
2)按声明顺序调用成员的初始化。
3)调用导出类构造器的主体。
最后子类中的对象,即组合来的对象引用,只要有可能就应该对他们进行初始化。但遗憾的是这种做法并不适用于所有情况。
构造器内部的多态方法的行为
Calss Glyph {
Void draw() {
Print(“Glyph.draw()”);
}
Glyph() {
Print(“Glyph() before draw()”);
Draw();
Print(“Glyph() after draw()”);
}
}
Class RoundGlyph extends Glyph {
Private int radies = 1;
RoundGlyph(int r) {
Radies = r;
Print(“RoundGlyph.RoundGlyph(), radies = ” + radies);
}
Void draw() {
Print(“RoundGlyph.draw(), radius = ” + radius);
}
}
Public class test {
Public static void main(String[] agers) {
New RoundGlyph(5);
}
}
结果:
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph() radies = 5
看上面的代码,我们会发现父类构造方法调用到的竟然是子类的draw方法。
初始化的实际过程:
1) 在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制的零。
2) 如前所述那样调用基类构造器。此时调用被覆盖后的draw()方法,由于1的缘故此时的radius的值是0。
3) 按照声明的顺序调用成员的初始化方法。
4) 调用导出类的构造器主体。
就是当调用到父类的构造器的时候,子类的成员变量还没有被初始化,但是方法什么的都已经加载完毕了,所以调用的是子类的方法,但是子类的成员变量没有初始化,所以为0.
因此,编写构造器时有一条有效的准则:“用尽可能简单的方法使对象进入正常状态;如果可以的画,避免调用其他方法”。在构造器内唯一能够安全调用的那些方法是基类中的final方法。这些方法不能被覆盖,因此也就不会出现上述令人惊讶的问题。你可能无法总是能够遵循这条准则,但是应该朝着它努力。
纯继承与扩展
导出类中接口的扩展部分不能被基类访问,因此,一旦我们向上转型,就不能调用那些新方法。
分享到:
相关推荐
Java第8章 继承和多态含源代码 Java第8章 继承和多态含源代码Java第8章 继承和多态含源代码 Java第8章 继承和多态含源代码 Java第8章 继承和多态含源代码 Java第8章 继承和多态含源代码
第8章--virtual函数与多态
Java程序设计:第8章 继承和多态.ppt
C++程序设计基础教程的第12章主要探讨了多态这一核心的面向对象编程概念。多态(Polymorphism)是C++中一个至关重要的特性,它允许一个接口(函数或运算符)根据调用时的具体对象类型表现出不同的行为。在本章中,...
继承和多态是C++中面向对象编程的两个核心概念,它们极大地增强了代码的灵活性、复用性和可扩展性。 **继承(Inheritance)** 继承是面向对象编程的基础,允许我们创建一个新的类(派生类)来扩展已有的类(基类)...
### Unity基础 C# 第六章 继承与多态 #### 一、继承的基本概念 在面向对象编程中,继承是一种强大的工具,它允许我们基于现有的类定义新的类。这不仅可以减少代码重复,还能使代码结构更加清晰。通过继承,子类会...
【C++程序设计课件:第八章 继承与多态】 在面向对象程序设计中,继承和多态是两个核心概念,它们极大地增强了代码的复用性和灵活性。本课件详细介绍了C++中这两个概念及其相关知识。 **继承(Inheritance)** ...
第1章 C#入门 ...1.1.2 认识C≠语言 1.2 Visual Studio.NET集成开发环境简介 1.2.1 VS.NET起始页 ...第8章 多态 第9章 接口 第10章 异常处理 第11章 委托和事件 第12章 文件操作 第13章 课程设计 参考文献
继承与多态 继承是面向对象编程(Object-Oriented Programming)中的一种机制,允许一个类继承另一个类的属性和行为。通过继承,子类可以重用父类的代码,减少代码的冗余和重复。同时,继承也可以实现多态性,即...
在C++语言中,继承与多态是面向对象编程的两个核心特性,它们不仅提供了代码复用的机制,还极大地增强了程序设计的灵活性和可扩展性。理解这些概念对于掌握C++的精髓至关重要。 首先,让我们深入探讨继承。继承是...
第8章内联函数 第9章命名控制 第10章引用和拷贝构造函数 第11章运算符重载 第12章动态对象创建 第13章继承和组合 第14章多态和虚函数 第15章模板和包容器类 第16章多重继承 第17章异常处理 第18章运行时类型识别
第1章 Java概述 第2章 Java语言基础 第3章 类的封装、继承和多态 第4章 接口、内部类和Java API基础 ...第8章 Applet应用程序 第9章 输入/输出流和文件操作 第10章 网络通信 第11章 数据库应用 第12章 综合应用设计
第10章 static修饰符.pptx 第10章 枚举.pptx 第11章 异常和断言.pptx 第12章 JDK8中的日期.pptx 第12章 字符串、日期.pptx 第13章 容器和泛型.pptx 第14章 流与文件(1)....第8章 包装器类.pptx 第9章 内部类.pptx
"北大青鸟C#第六章 初始继承和多态参考答案.zip"这个压缩包文件包含了与北大青鸟S2阶段C# OOP相关的上机练习、课后作业和示例的解答,重点讲解了继承和多态这两个关键的OOP特性。 1. 继承:继承是面向对象编程中的...
第8章 指针 第9章 构造数据类型 第10章 类和对象 第11章 继承 第12章 多态 第13章 运算符重载 第14章 输入/输出流 第15章 文件 第16章 命名空间 第17章 引用与内存管理 第18章 标准...
#### 8. 对象的创建过程 **示例 12.8** ```python class A: def __new__(cls): cls.__init__(cls) print("A's __new__() invoked") def __init__(self): print("A's __init__() invoked") class B(A): def __...
Java语言程序设计ppt第十一章(继承和多态) 本章节主要讲解Java语言中的继承和多态机制,包括继承的定义、继承的应用、多态性和动态绑定等知识点。 一、继承的定义 继承是一种机制,允许一个类继承另一个类的...
【完整课程列表】 完整版 Java编程基础入门教程 ...完整版 Java编程基础入门教程 Java语言程序设计 第8章_多线程与异常处理(共72页).ppt 完整版 Java编程基础入门教程 Java语言程序设计 第9章_Applet(共40页).ppt