您的位置:首页 > 编程语言 > Java开发

Java编程思想第四版读书笔记——第八章 多态

2016-06-20 22:23 309 查看
本来不打算看了,现在面试笔试发现还是要重新拾起来看一遍。老老实实啃砖吧

第八章 多态

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

“封装”通过合并特征和行为来创建新的数据类型。(合并成员函数和方法创建类)

“多态”消除类型之间的耦合关系。

1、向上转型

子类对象的引用向上转型为基类,传递到相应方法中。

2、转机

将一个方法调用同一个方法主体关联起来被称作绑定
程序执行前的绑定(由编译器和连接程序实现),称为前期绑定
运行时根据对象的类型进行绑定,称为后期绑定,也称为动态绑定或运行时绑定。
Java中除了static方法和final方法(private属于final方法)外,其它所有方法都是动态绑定。
多态让程序员将“改变的事物与未改变的事物分离开来”。
只有非private方法才能被覆盖,当然覆盖private类时,编译器不会报错。但是导出类和基类中的该同名方法,是两个不同的方法,向上转型为基类调用时,会调用基类的那个private的方法。
静态方法是与类,而非单个对象关联的,因此不是多态的。

任何域访问操作都有编译器解析,因此不是多态的。

当Sub对象转型为Super使用时,任何域访问操作都将由编译器解析,因此不是多态的。(在包含相同成员变量时,子类包含两个域,基类和自己的,当要调用基类中该重名成员变量时,系统不会多态的自动的调用基类的该变量,需要显式的指明super.成员变量。)

3、构造器和多态

当有多重继承关系时,调用构造器顺序:

基类构造器 -> 成员的初始化方法 -> 子类构造器

在销毁时,需要显式的调用基类的dispose()方法,销毁的顺序和初始化相反,包括字段的销毁顺序和申明的顺序相反。共享数据最后dispose()。

构造器内部的多态方法的行为:

在初始化时,基类构造器中调用子类中覆盖的方法,此时子类的成员变量未赋值,如果此时对其操作可能会产生意想之外的结果。所以应该避免这样做。在构造器内唯一能够安全调用的事基类中的final方法。

4、协变返回类型

子类中被覆盖的方法可以返回基类方法所返回类型的子类,这样虽然返回值类型不同,但是也算覆盖。

5、用继承进行设计

组合更加灵活,首选组合。

用继承表达行为间的差异,用字段表达状态上的变化。

状态设计模式

创建一个基类的引用,通过方法改变其所指向的对象类型(子类们),调用相同的方法,行为产生变化。(调用了相应子类的方法)。 这样可以实现动态灵活性。

如下所示:

import static net.mindview.util.Print.*;

class Actor {

public void act() {}

}

class HappyActor extends Actor {

public void act() { print("HappyActor"); }

}

class SadActor extends Actor {

public void act() { print("SadActor"); }

}

class Stage {

private Actor actor = new HappyActor();

public void change() { actor = new SadActor(); }

public void performPlay() { actor.act(); }

}

public class Transmogrify {

public static void main(String[] args) {

Stage stage = new Stage();

stage.performPlay();

stage.change();

stage.performPlay();

}

} /* Output:

HappyActor

SadActor

对于子类扩展基类接口的情况,向上转型后不能调用子类的不同于基类的新方法。

这样需要用到向下转型,在Java中,所有的转型都会对其进行检查。称为“运行时类型识别”(RTTT)如果转型正确,则转型成功;如果所转类型不是正确的类型,则转型失败,返回ClassCastException异常。

父类引用可以指向子类对象,子类引用不可以指向父类对象。

比如:

class Useful {

public void f() {}

public void g() {}

}

class MoreUseful extends Useful {

public void f() {}

public void g() {}

public void u() {}

public void v() {}

public void w() {}

}

public class RTTI {

public static void main(String[] args) {

Useful[] x = {

new Useful(),

new MoreUseful()

};

x[0].f();

x[1].g();

// Compile time: method not found in Useful:

//! x[1].u();

((MoreUseful)x[1]).u(); // Downcast/RTTI

((MoreUseful)x[0]).u(); // Exception thrown

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息