Java编程思想之八多态
在面向对象的程序设计语言中,多态是继数据和继承之后的第三张基本特征
多态不但能够改善代码组织结构和可读性,还能够创建可扩展的程序——即无论在项目最初创建时还是在需要添加新功能时都可以"生长"的程序。
封装通过合并特征和行为来创建新的数据类型。"实现隐藏"则通过将细节"私有化",把接口和实现分离开来。多态的作用就是消除类型之间的耦合关系。
多态方法调用允许一种类型表现出与其他相似类型之间的区别。
8.1 再论向上转型
把某个对象的引用视作对其基类的引用称为向上转型——因为再继承树中,基类是放置在上方的。
8.2 转机
基类如何知道引用指向哪个导出类?
8.2.1 方法调用绑定
将一个方法调用同一个方法主体关联起来被称作绑定。若在程序执行前进行绑定,由编译器和连接程序实现,叫做前期绑定,此为面向过程语言默认绑定方式。
后期绑定:就是在运行时,根据对象的类型进行绑定。后期绑定也叫做动态绑定或运行时绑定。
Java中除了satic方法和final方法之外,其他所有都是后期绑定。
8.2.3 可扩展性
在一个设计良好的OOP程序中,程序是可扩展的,因为可以从通用的基类继承出新的数据类型,从而新添一些功能。那些操作基类接口的方法不需要任何改动就可以应用于新类。
8.2.4 缺陷:覆盖私有方法
public class PrivateOverride {
private void f(){
System.out.println("private f()");
}
public static void main(String[] args){
PrivateOverride po=new Derived();
po.f();
}
}
class Derived extends PrivateOverride{
public void f(){
System.out.println("public f()");
}
}
只有非private方法才可以被覆盖,在导出类中,对于基类的private方法,最好采用不同的名字。
8.2.5 缺陷:域与静态方法
public class FieldAccess {
public static void main(String[] args){
Super sup=new Sub();
System.out.println("sup.feld="+sup.field+",sup.getField()="+sup.getField()+"");
//output:sup.feld=0,sup.getField()=1
Sub sub=new Sub();
System.out.println("sub.field="+sub
.field+",sub.getField()="+sub.getField()+",getSuperField="+sub.getSuperField()+"");
//output:sub.field=1,sub.getField()=1,getSuperField=0
}
}
class Super{
public int field=0;
public int getField(){
return field;
}
}
//Sub包含了两个域,自己的field和继承来的field
class Sub extends Super{
public int field=1;
public int getField(){
return field;
}
public int getSuperField(){
return super.field;
}
}
如果某个方法是静态的,它的行为就不具有多态性
public class StaticPolymorphism {
public static void main(String[] args){
StaticSuper sup=new Staticsub();
System.out.println(sup.staticGet());//output:Base staticGet()
System.out.println(sup.dynamicGet());//output:Derived dynamicGet()
}
}
class StaticSuper{
public static String staticGet(){
return "Base staticGet()";
}
public String dynamicGet(){
return "Base dynamicGet()";
}
}
class Staticsub extends StaticSuper{
public static String staticGet(){
return "Derived staticGet()";
}
public String dynamicGet(){
return "Derived dynamicGet()";
}
}
静态方法是与类,而非与单个的对象相关联
8.3 构造器和多态
构造器并不具有多态性,它们实际上是static方法,只不过该static声明是隐试的。
8.3.1 构造器的调用顺序
基类构造器总是在导出类的构造过程中被调用,而且按照继承层次逐渐向上链接,以使每个基类的构造器都能得到调用。意义:构造器具有一项特殊的任务,检查对象是否被正确的构造。导出类只能访问它自己的成员,不能访问基类中的成员(基类成员通常使private类型)。只有基类的构造器才具有恰到的知识权限来对自己的元素进行初始化。
对象调用构造器遵循以下顺序:
- 1.调用基类构造器
- 2.按声明顺序调用成员初始化方法
- 3.调用导出类构造器的主体
8.3.2 继承与清理
通过组合和继承方法来创建新类时,永远不必担心对象的清理问题,子对象通常都会留给垃圾回收器进行处理。
8.3.3 构造器内部的多态方法的行为
如果调用构造器内部的一个动态绑定方法,就要用到哪个方法的覆盖后的定义。然而,这个调用效果可能难以预测,因为被覆盖的方法在对象完全构造之前就会被调用。
public class PolyConstructors {
public static void main(String[] args){
new RoundGlyph(5);
}
}
class Glyph{
void draw(){
System.out.println("Glyph.draw()");
}
Glyph(){//2
System.out.println("Glyph() before draw()");//3
draw();//4
System.out.println("Glyph() after draw()");//6
}
}
class RoundGlyph extends Glyph{
private int radius=1;//7
RoundGlyph(int r){//1
radius=r;//8
System.out.println("RoundGlyph.RoundGlyph().radius="+radius+"");//9
}
void draw(){
System.out.println("RoundGlyph.draw(),radius="+radius+"");//5
}
}
初始化过程:
- 1.在其他任何事物发送之前,将分配对象的存储控件初始化成二进制零
- 2.调用基类构造器
- 3.按照声明顺序调用成员初始化方法
- 4.调用导出类的构造器主体
Java编程思想之八多态的更多相关文章
- 【学习笔记】JAva编程思想之多态
1.如果java的基类拥有某个已被多次重载的方法名称,那么在导出类中重新定义该方法名称并不会屏蔽在基类的任何版本.因此,无论是在该层或者他的基类中对方法进行定义,重载机制都可以正常工作. 2.使用@O ...
- 《java编程思想》多态与接口
向上转型 定义:把某个对象的引用视为对其基类类型的引用的做法被称为向上转型方法调用绑定 将一个方法调用同一个方法主体关联起来被称作绑定. 前期绑定:程序执行前进行的绑定叫做前期绑定,前期绑定也是jav ...
- (七)《Java编程思想》——多态的缺陷
1.不能“覆盖”私有方法 package chapter8; /** * 不能"覆盖"私有方法 */ public class PrivateOverride { private ...
- Java编程思想(四) —— 复用类
看了老罗罗升阳的专訪,不由自主地佩服,非常年轻,我之前以为和罗永浩一个级别的年龄.也是见过的不是初高中编程的一位大牛之中的一个,专訪之后.发现老罗也是一步一个脚印的人. 别说什么难做,做不了.你根本就 ...
- Java编程思想学习(一)----对象导论中多态的理解
1.1抽象过程 1)万物皆对象. 2)程序是对象的集合,他们通过发送消息来告知彼此所要求做的. 3)每个对象都有自己的由其他对象所构成的存储. 4)每个对象都拥有其类型. 5)某一特定类型的所有对象都 ...
- 《Java编程思想》学习笔记_多态
多态 多态指一个行为产生多种状态,针对父类类型可接收其子类类型,最终执行的状态由具体子类确定,其不同子类可呈现出不同状态.例如人[父类]都会跑步[行为],但小孩[子类]跑步.成年人[子类]跑步.运动员 ...
- 《Java编程思想》学习笔记(二)——类加载及执行顺序
<Java编程思想>学习笔记(二)--类加载及执行顺序 (这是很久之前写的,保存在印象笔记上,今天写在博客上.) 今天看Java编程思想,看到这样一道代码 //: OrderOfIniti ...
- Java编程思想重点笔记(Java开发必看)
Java编程思想重点笔记(Java开发必看) Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...
- java编程思想-复用类总结
今天继续读<java 编程思想>,读到了复用类一章,看到总结写的很好,现贴上来,给大家分享. 继承和组合都能从现有类型生成新类型.组合一般是将现有类型作为新类型底层实现的一部分来加以复用, ...
随机推荐
- localStorage、sessionStorage、Cookie的区别及用法
1.webstorage 本地存储,存储在客户端,包括localStorage和sessionStorage. (1)localStorage:生命周期是永久,这意味着除非用户显示在浏览器提供的UI上 ...
- 常用的本地存储-----cookie篇
1.引言 随着浏览器的处理能力不断增强,越来越多的网站开始考虑将数据存储在「客户端」,那么久不得不谈本地存储了. 本地存储的好处: 一是避免取回数据前页面一片空白,如果不需要最新数据也可以减少向服务器 ...
- 模块化规范:AMD规范和CommonJs规范
为什么模块很重要? 因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块. 但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写法,岂不是乱 ...
- java学习(2):类和对象
一.类 类可以看成是创建对象的模板,它描述一类对象的行为和状态.创建对象也叫类的实例化.类必须先定义才能使用. 通过下面一个简单的类来理解下Java中类的定义: public class Dog { ...
- Python小练习:批量删除多个文件夹内的相同文件
应用场景: 下载的多个文件夹是压缩包,解压后每个文件夹都有某个网站的推广链接,想要批量的删除该文件 使用环境:win7,python3.6 代码: 1.直接用for循环 由于os.walk()方法自带 ...
- Fiddler抓websocket协议的包,用jmeter做并发测试
1.Fiddler: 左边为ws请求url.右边为请求数据,响应数据 jmeter:
- jmeter中设置线程数与设置集合点的区别
1.设置线程数: 表示10秒内启动50个线程, 运行结果如下:10秒内启动了50个线程 2.设置集合点: Number of Simulated Users to Group by:50,表示集合50 ...
- Java并发编程:ThreadPoolExecutor + Callable + Future(FutureTask) 探知线程的执行状况
如题 (总结要点) 使用ThreadPoolExecutor来创建线程,使用Callable + Future 来执行并探知线程执行情况: V get (long timeout, TimeUnit ...
- 【BZOJ 4004】 装备购买(高斯消元+贪心)
装备购买 题目 脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装备有 m 个属性,用向量zi(aj ,.....,am) 表示 (1 <= i <= n; 1 <= j ...
- 五个wordpress调用随机文章的方法
分享几个WordPress不用插件调用随机文章的方法,不仅增强用户粘性,而且当蜘蛛来爬你的文章的时候每次都会有变化,搜索引擎很喜欢.主要用到的是orderby rand参数,下面就随ytkah一起来看 ...