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 编程思想>,读到了复用类一章,看到总结写的很好,现贴上来,给大家分享. 继承和组合都能从现有类型生成新类型.组合一般是将现有类型作为新类型底层实现的一部分来加以复用, ...
随机推荐
- layui 表格中实现照片预览,点击查看原图
人员表格中实现照片预览,并且可点击放大.查看原图 <table id="dutyInfoTable" class="layui-hide">< ...
- 如何检测Windows中的横向渗透攻击
一.前言 横向渗透攻击技术是复杂网络攻击中广泛使用的一种技术,特别是在高级持续威胁(Advanced Persistent Threats,APT)中更加热衷于使用这种攻击方法.攻击者可以利用这些技术 ...
- AES加密解密工具类封装(AESUtil)
package club.codeapes.common.utils; import org.springframework.util.Base64Utils; import javax.crypto ...
- Redis的内存分配
内存分配 Redis进程的内存消耗主要包括:自身内存 + 对象内存 + 缓冲内存 + 内存碎片.1 自身内存 Redis自身内存消耗非常少,通常used_memory在800KB左右,used_mem ...
- 微服务框架---搭建 go-micro环境
1.安装micro 需要使用GO1.11以上版本 #linux 下 export GO111MODULE=on export GOPROXY=https://goproxy.io # windows下 ...
- SpringCloud2.0 Feign 服务发现 基础教程(五)
1.启动[服务中心]集群,即 Eureka Server 参考 SpringCloud2.0 Eureka Server 服务中心 基础教程(二) 2.启动[服务提供者]集群,即 Eureka Cli ...
- Vue开发之基础路由
1.router-link和router-view组件 src/App.vie文件内容: <template> <div id="app"> <div ...
- XXX接口自动化测试方案
XXX接口自动化测试方案 1.引言 1.1 文档版本 版本 作者 审批 备注 V1.0 XXXX 创建测试方案文档 1.2 项目情况 项目名称 XXX 项目版本 V1.0 项目经理 XX 测试人员 X ...
- Pandas快速上手(一):基本操作
本文包含一些 Pandas 的基本操作,旨在快速上手 Pandas 的基本操作. 读者最好有 NumPy 的基础,如果你还不熟悉 NumPy,建议您阅读NumPy基本操作快速熟悉. Pandas 数据 ...
- js动画--透明度变化
对于设置元素的透明度的变化.主要思想也是通过一个定时器来控制的. 此外对于透明度有一点要说明一下,就是在IE中我们在css中设置透明度的方式filter:alpha(opacity:value)其中v ...