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

Java-polymorphism-01

2008-04-20 17:06 225 查看
面向对象的三种基本特征:数据抽象、继承和多态。
数据抽象即抽象数据类型(abstract data type, ADT),这其中包含三层含义:封装、信息/实现隐藏和状态保持(参加blog:Java-面向对象含义)。
多态通过分离“做什么”和“怎么做”(可以有多种方法实现“怎么做”,这也是之所以称为多态的原因),从另一角度将接口和实现(or基类与子类or子类与子类)分离开来。
ps:实际上“基类和子类”也可以理解成是“接口和实现”的关系。
“封装”通过合并特征和行为来创建新的数据类型;“实现隐藏”则通过将细节私有化(private)把接口和实现分离开来;而多态的作用则是消除类型之间的耦合关系(即使不同类中的同一方法彼此间没有耦合关系,参加blog:Java-面向对象含义 求多边形面积的例子)。
继承允许将对象视为它自己本身的类型或其基类型来加以处理。这种能力极为重要,因为它允许将多种类型(从同一基类导出的)视为同一类型来处理。而同一份代码也就可以毫无差别地运行在这些不同类型之上了。多态方法允许一种类型表现出与其他相似类型之间的区别(即对同一实现目标在实现方法上的区别,这种区别是根据方法行为的不同而表现出来的),只要它们都是从同一基类导出的。

再论向上转型
对象既可以作为它自己本身的类型使用,也可以作为它的基类使用。这种把对某个对象的引用视为对其基类的引用的做法称为“向上转型”。




/** *//**


* Title: Notes to play on musical instruments<br>


* Description: 此例解释"向上转型"概念, 无任何功能接口<br>


* Company: Augmentum Inc<br>


* Copyright: (c) 2008 Thinking in Java<br>


* @author Forest He


* @version 1.0


*/


package com.augmentum.foresthe;




class Note ...{


private String noteName;




private Note (String noteName)...{ this.noteName = noteName; }




public String toStirng() ...{ return noteName; }


public static final Note


MIDDLE_C = new Note("MIDDLE_C"),


C_SHARP = new Note("C_SHARP"),


B_FLAT = new Note("B_FLAT");


}




/**//*Note类是一个枚举类,包含固定数目的、可供选择的不变对象。Note类外不能再产生另外的对象,因为其Constructor是私有的*/






class Instrument ...{




public void play(Note note) ...{ System.out.println("Intrument.play() " + note.toStirng()); }


}




class Wind extends Instrument ...{




public void play(Note note) ...{ System.out.println("Wind.play() " + note.toStirng()); }


}




class Music ...{




public static void tune(Instrument instrument) ...{ instrument.play(Note.MIDDLE_C); }




public static void main(String[] args) ...{


Wind flute = new Wind();


tune(flute); //Upcasting


}


}

Music.tune()方法接受一个Instrument引用,同时也接受任何导出自Instrument的类。在main()中,当一个Wind引用传递到tune()方法时,就会出现这种情况,而不需要任何类型转换(Instrument的接口必定存在于Wind中)。从Wind向上转型为Instrument可能会“缩小”接口,但不会比Instrument的全部接口更窄。
如果让tune()方法直接接受一个Wind引用作为自己的参数,似乎会更为直观。但这样引发的一个重要问题是:如果那样做,就需要为系统内Instrument的每种类型都编写一个新的tune()方法(例如Stringed弦乐和Brass管乐)。所以我们只接收基类作为参数,而不是导出类。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: