在面向对象的程序设计语言中,多态是继数据和继承之后的第三张基本特征

多态不但能够改善代码组织结构和可读性,还能够创建可扩展的程序——即无论在项目最初创建时还是在需要添加新功能时都可以"生长"的程序。

封装通过合并特征和行为来创建新的数据类型。"实现隐藏"则通过将细节"私有化",把接口和实现分离开来。多态的作用就是消除类型之间的耦合关系。

多态方法调用允许一种类型表现出与其他相似类型之间的区别。

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编程思想之八多态的更多相关文章

  1. 【学习笔记】JAva编程思想之多态

    1.如果java的基类拥有某个已被多次重载的方法名称,那么在导出类中重新定义该方法名称并不会屏蔽在基类的任何版本.因此,无论是在该层或者他的基类中对方法进行定义,重载机制都可以正常工作. 2.使用@O ...

  2. 《java编程思想》多态与接口

    向上转型 定义:把某个对象的引用视为对其基类类型的引用的做法被称为向上转型方法调用绑定 将一个方法调用同一个方法主体关联起来被称作绑定. 前期绑定:程序执行前进行的绑定叫做前期绑定,前期绑定也是jav ...

  3. (七)《Java编程思想》——多态的缺陷

    1.不能“覆盖”私有方法 package chapter8; /** * 不能"覆盖"私有方法 */ public class PrivateOverride { private ...

  4. Java编程思想(四) —— 复用类

    看了老罗罗升阳的专訪,不由自主地佩服,非常年轻,我之前以为和罗永浩一个级别的年龄.也是见过的不是初高中编程的一位大牛之中的一个,专訪之后.发现老罗也是一步一个脚印的人. 别说什么难做,做不了.你根本就 ...

  5. Java编程思想学习(一)----对象导论中多态的理解

    1.1抽象过程 1)万物皆对象. 2)程序是对象的集合,他们通过发送消息来告知彼此所要求做的. 3)每个对象都有自己的由其他对象所构成的存储. 4)每个对象都拥有其类型. 5)某一特定类型的所有对象都 ...

  6. 《Java编程思想》学习笔记_多态

    多态 多态指一个行为产生多种状态,针对父类类型可接收其子类类型,最终执行的状态由具体子类确定,其不同子类可呈现出不同状态.例如人[父类]都会跑步[行为],但小孩[子类]跑步.成年人[子类]跑步.运动员 ...

  7. 《Java编程思想》学习笔记(二)——类加载及执行顺序

    <Java编程思想>学习笔记(二)--类加载及执行顺序 (这是很久之前写的,保存在印象笔记上,今天写在博客上.) 今天看Java编程思想,看到这样一道代码 //: OrderOfIniti ...

  8. Java编程思想重点笔记(Java开发必看)

    Java编程思想重点笔记(Java开发必看)   Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...

  9. java编程思想-复用类总结

    今天继续读<java 编程思想>,读到了复用类一章,看到总结写的很好,现贴上来,给大家分享. 继承和组合都能从现有类型生成新类型.组合一般是将现有类型作为新类型底层实现的一部分来加以复用, ...

随机推荐

  1. 上传文件至Github仓库

    Github的使用 创建一个本地的版本库(也就是一个文件夹) 新建文件夹,或使用Git bash命令行窗口创建 $ mkdir test $ cd test 在命令行中输入 git init把这个文件 ...

  2. 关于DataX

    1. 关于DataX 1.1. 前言 为什么写这篇文章,因为初出茅庐的时候,曾经遇到的一个面试官就是DataX的作者之一,而当时我还偏偏因为业务需求做了个数据库的同步工具,我当时不知道他做过这么专业的 ...

  3. 分享整理vue.js在日常工作中用到的组件,帮助你在vue应用中快速开发

    Vue-Echarts vue-echarts是封装后的vue插件, 基于 ECharts v4.0.1+ 开发,依赖 Vue.js v2.2.6+,功能一样的只是把它封装成vue插件 这样更方便以v ...

  4. MyBatis面试题整理

    MyBatis面试题整理 1.什么是MyBatis? 答:MyBatis是一个可以自定义SQL.存储过程和高级映射的持久层框架. 2.讲下MyBatis的缓存 答:MyBatis的缓存分为一级缓存和二 ...

  5. Maven项目中jstl表达式失效

    从网上看到的可能原因: 1.包没导入 2.web.xml版本太低,不支持 最后,我一直忽略了的解决办法: 关于jstl和el表达式失效的解决办法 - - ITeye博客 https://aazham. ...

  6. 发送短信验证码的JAVA代码

    package com.moretickets.platform; import com.alibaba.fastjson.JSONException; import com.alibaba.fast ...

  7. .gitignore 标准模板 -适用于SpringBoot+Vue项目 -Idea+VSCode开发

    .gitignore 标准模板 -适用于SpringBoot+Vue项目 node_modules/ target/ !.mvn/wrapper/maven-wrapper.jar ### STS # ...

  8. Centos7.x for aarch64 下载地址

    ARM64架构系统 CentOS7镜像下载源 http://archive.kernel.org/centos-vault/altarch/ 例如:centos7.5 http://archive.k ...

  9. Hive元数据配置到MySql

    1 驱动拷贝 1.在/opt/software/mysql-libs目录下解压mysql-connector-java-5.1.27.tar.gz驱动包 [root@hadoop102 mysql-l ...

  10. 没有内置小鹤双拼的rime输入法就是差劲

    没有内置小鹤双拼的rime输入法就是差劲,还特立独行,搞什么繁体~ 没有内置小鹤双拼的rime输入法就是差劲,还特立独行,搞什么繁体~ 没有内置小鹤双拼的rime输入法就是差劲,还特立独行,搞什么繁体 ...