Java编程思想---第八章 多态(上)

第八章  多态(上)

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

  多态通过分离做什么和怎么做,从另一角度将接口和实现分离开来,多态不但能改善代码的组织结构和可读性,还能够创建可扩展的程序,无论在项目最初创建时还是在需要添加新功能时都可以生长程序。封装通过合并特征和行为来创建新的数据类型。

8.1 再论向上转型

  在上一章中我们已经知道,对象可以作为它本身的类型使用,也可以作为它的基类使用,而这种把对某个对象的引用视为对其基类的引用的做法被称为向上转型。

//: demo/Note.java

package com.example.demo;

public enum Note {
    MIDDLE_C, C_SHARP, B_FLAT;
}

//: demo/Instrument.java
package com.example.demo;
public class Instrument {
    public void play(Note n) {
        System.out.println("Instrument.play()");
    }
}

//: demo/Wind.java
package com.example.demo;
public class Wind extends Instrument {
    public void play(Note n) {
        System.out.println("Wind.play()" + n);
    }
}

//: demo/Music.java
package com.example.demo;

public class Music {
    public static void tune(Instrument i) {
        i.play(Note.MIDDLE_C);
    }

    public static void main(String[] args) {
        Wind flute = new Wind();
        tune(flute);
    }
}

  输出结果为:

  Wind.play()MIDDLE_C

  导出类可以接受基类的所有接口,向上转型可能会使接口“缩小”,但不会比基类的全部接口更窄。

8.1.1 忘记对象类型

package com.example.demo;

class Stringed extends Instrument {
    public void play(Note n) {
        System.out.println("Stringed.play() " + n);
    }
}

class Brass extends Instrument {
    public void play(Note n) {
        System.out.println("Brass.play() " + n);
    }
}

public class Music2{
    public static void tune(Wind i) {
        i.play(Note.MIDDLE_C);
    }

    public static void tune(Stringed i) {
        i.play(Note.MIDDLE_C);
    } 

    public static void tune(Brass i) {
        i.play(Note.MIDDLE_C);
    }

    public static void main(String[] args) {
        Wind flute = new Wind();
        Stringed violin = new Stringed();
        Brass frenchHorn = new Brass();
        tune(flute);
        tune(violin);
        tune(frenchHorn);
    }
}

  输出结果为:

Wind.play()MIDDLE_C

Stringed.play() MIDDLE_C

Brass.play() MIDDLE_C

  如果我们忘记重载某个方法,编译器不会返回任何错误信息,这样关于类型的整个处理过程就变得难以操纵。如果我们只写一个简单方法,它只接受基类作为参数,而不是那些特殊的导出类,会不会更好?这正是多态所允许的,然而大多数程序员具有面向过程程序设计的背景,对多态的运作方式可能会有一点迷惑。

8.2 转机

8.2.1 方法调用绑定

  将一个方法调用同一个方法主体关联起来被称作绑定。如果在程序执行前进行绑定,叫做前期绑定。上面的程序之所以令人费解,主要是因为前期绑定,当编译器只有一个Instrument引用时,它无法知道究竟调用哪个方法才对。解决方法是后期绑定,他的含义就是在运行时根据对象的类型进行绑定。

  Java中除了static方法和final方法之外,其他所有方法都是后期绑定,这意味着通常情况下我们不必判定是否应该进行后期绑定,它也会自动发生。调用final可以防止其他人覆盖该方法,但更重要的一点是,这样可以有效关闭动态绑定,这样编译器就可以为final调用生成更有效的代码,

8.2.2 产生正确的行为

  一旦知道Java中所有方法都是通过动态绑定实现多态这是事实之后,我们就可以编写只与基类打交道的代码程序,并且这些代码对所有导出类都可以正确运行。

  在几何形状这个例子中,有一个基类Shape以及多个导出类,下面的继承图展现他们之间的关系:

  向上转型可以像下面这条语句这么简单:

Shape s = new Circle();

  这里创建了一个Circle对象并把得到的引用赋值给Shape,这看似错误但实际上是没问题的,因为通过继承,Circle就是一种Shape。

  假设你调用一个基类方法,并且它在导出类中被覆盖:

s.draw();

  你可能再次认为调用的是Shape的draw()方法,因为这毕竟是一个Shape引用,那么编译器是怎么样知道去做其他事情的呢?由于后期绑定,也就是多态,还是正确调用了Circle.draw()方法。

  Shape基类为从它那里继承而来,也就是说,所有的行传都可以描绘和删除,导出类通过覆盖这些定义,来为每种特殊类型的几何形状提供单独的行为。

8.2.3 可扩展性

  现在我们返回到乐器示例。由于有多态机制,我们可以根据自己的需求对系统添加任意多的新类型,而不需要该tune()方法。在一个设计良好的OOP程序中,大多数方法都会遵循tune()的模型,而且只与基类接口通信。这样的程序时可扩展的,因为可以从通用的基类继承出新的数据类型从而添加一些功能,那些草丛基类接口的方法不需要任何改动就可以应用于新类。

  我们向乐器的基类添加更多的方法,并加入一些新类:

  事实上,不需要改动tune()方法,所有新类都能与原有类一起正确运行,及时tune()是单独放在某个文件中,并且在Instrument接口中添加了其他的新方法,tune()也不需要编译就能正确运行。下面是上图的具体实现:

原文地址:https://www.cnblogs.com/parable/p/11470203.html

时间: 2024-10-10 04:17:42

Java编程思想---第八章 多态(上)的相关文章

java编程思想第八章多态

前言: 封装:通过合并特征和行为创建新的数据类型. 实现隐藏:通过将细节"私有化",把接口和实现分离. 多态:消除类型间的耦合关系.也称作动态绑定,后期绑定或运行时绑定. 8.1再论向上转型: 对象既可以作为本身的类型使用,也可以作为基类的类型使用.这种做法成为向上转型. 其代码表现就是:父类引用指向子类. 多态允许在参数的地方使用,即参数处声明基类,用于接受基类或导出类实现. 8.2转机(主要是介绍如何实现多态) 为了解决多态问题,在java中提供了后期绑定的方法,即在运行时根据对象

Java编程思想之8多态

这一章看下来,感觉比较混乱.乱感觉主要乱在8.4  8.5. 开始读的时候,感觉8.1 8.2 8.3都挺乱的.读了两遍后发现前三节还是比较有条理的. 8.1主要讲了什么是多态,多态的好处. 8.2主要讲了什么情况会发生多态?? 8.3主要讲了构造器内部里面的方法调用会发生多态. 8.4就一页,而且感觉一般用不到.用到了再看也行. 8.5也很简单,相当于一个总结,一个补充(向下转型) 我主要根据书上的内容,总结两个内容: 1.什么是多态,多态的好处: 2.什么情况下会发生多态?为什么这些情况下会

【Java编程思想】8.多态

在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种基本特征. 多态分离了"做什么"和"怎么做",让接口和实现分离开,改善了代码的可读性和组织结构,创建了可拓展的程序. 封装,通过合并特征和行为来创建新的数据类型. 实现隐藏,通过将细节"私有化"把接口和实现分离开来. 多态,消除类型之间的耦合联系.多态方法调用允许一种类型表现出与其他相似类型之间的区别,只要他们都是从同一基类导出来的.-->这种区别是根据方法行为的不同而表示出来的

Java编程思想学习(六) 多态

1.Java语言的三大特性:继承.封装和多态. 继承:复用类的一种方法,可以简省很多代码: 封装:通过合并特征和行为来创建新的数据类型.[这种“数据类型”跟Java本身提供的8大“基本数据类型”的地位完全相同.Java通过封装这种方式来扩充数据类型.] 多态:消除创新的数据类型之间的耦合关系. 2.前期绑定:static和final方法都是前期绑定(在编译时绑定和执行): 3.后期绑定:Java中除了static和final方法,都是后期绑定(前面提到过,private方法属于final方法).

Java编程思想笔记(多态)

      1.再论向上转型:       1(1).忘记对象类型       2.转机:       2(1).方法调用绑定       2(2).产生正确的行为       2(3).可扩展性:多态是一项让程序员“将改变的事物与未变的事物分离开来”的重要技术.   2(4).缺陷:“覆盖”私有方法:只有非private方法才可以被覆盖:但是还需要密切注意覆盖private方法的现象,这时虽然编译器不会报错,但是也不会按照我们所期望的来执行.确切地说,在导出类中,对于基类中的private方法

Java编程思想(五) —— 多态(上)

上一章,Java编程思想(四) -- 复用类里面讲到了向上转型,感觉和多态放在一起写更好. 多态,polymorphism.一个重要的特性,篇幅太长了,分上下两篇写. (1)向上转型 class TV{ public static void show(TV tv){ System.out.println("TV"); } } public class LeTV extends TV{ public static void main(String[] args) { LeTV letv

《On Java 8》中文版,又名《Java 编程思想》中文第五版

来源:LingCoder/OnJava8 主译: LingCoder 参译: LortSir 校对:nickChenyx E-mail: [email protected] 本书原作者为 [美] Bruce Eckel,即(Thinking in Java 4th Edition,2006)的作者. 本书是事实上的 Thinking in Java 5th Edition(On Java 8,2017). Thinking in Java 4th Edition 基于 JAVA 5 版本:On

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

Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面 试过程中,而且在大型项目开发中也是常用的知识,既有简单的概念理解题(比如is-a关系和has-a关系的区别),也有深入的涉及RTTI和JVM底层 反编译知识. 1. Java中的多态性理解(注意与C++区分) Java中除了static方法和final方法(private方法本质上属于final方法,因为不能被子类访问)之外,其它所有的方法都是动态绑定,这意

java编程思想总结(三)

java编程思想总结(三) java编程思想总结是一个持续更新的系列,是本人对自己多年工作中使用到java的一个经验性总结,也是温故而知新吧,因为很多基础的东西过了这么多年,平时工作中用不到也会遗忘掉,所以看看书,上上网,查查资料,也算是记录下自己的笔记吧,过一段时间之后再来看看也是蛮不错的,也希望能帮助到正在学习的人们,本系列将要总结一下几点: 面向对象的编程思想 java的基本语法 一些有趣的框架解析 实战项目的整体思路 代码的优化以及性能调优的几种方案 整体项目的规划和视角 其它遗漏的东西