1 回答
TA贡献883条经验 获得超454个赞
单说你的这一句问题“不能重新定义一个抽象类来描述两个对象的特征吗?”
其实是可以这样定义的。
假如你的程序中只有“智能机类”和“PSP类”这两个类,并且你只是想单纯地对这两个进行抽象,那可以像你说的这样:抽象出一个“可玩游戏的电子产品类”。 然后从它派生出“能打电话的可玩游戏电子产品——手机”和“专门玩游戏的电子产品——PSP”。 这样使用单继承也还算能勉强适合这种简单的抽象。
不过你有没有觉得这样抽象在逻辑上似乎不那么贴切?
智能机本质是手机,玩游戏并不是必备功能,所以按说“智能机类”可以继承自“手机类”。“手机类”可以有打电话的功能。
而 PSP 本身就是游戏机,也许可以让它继承自“掌机类”。
掌机和手机在概念上没什么关系,也就不适合从更低层的“玩游戏的电子产品”继承而来了。
所以当你想扩展你的程序、加入更多的抽象层次时,如果仍只采用类来抽象而不用接口的话,就会遇到很多麻烦。而这正是因为 Java 中没有多继承。
因为 Java 没有多继承,也就不能用 同时继承多个基类的办法 来表示同时具有多个抽象概念。 所以就引入了“接口”来表达不同的抽象概念。而且这样还能很好地进行语义上的区分:
class 在语法上表示类型,并且多个 class 可以组织成继承体系来表示不同抽象层次的类型。在语义层面上用 class 来表示“对象”(以此进行所谓“面向对象”编程),并且在语义上 class 偏向对“实体”的抽象。
interface 并不是 class。在语法层面上你可以把 interface 看作是对 class 施加的规范——它要求实现它的 class 必须实现相应的 method 等。 而 interface 在语义上更偏向于对“功能”的抽象。
所以你最后一句话的理解方向是对的! Java 在设计上没有选择使用多继承,而是选择通过接口来对“对象的各种功能特性”作抽象,因此接口可以进行多继承,接口也可以组织成继承体系。 这样的好处是可以在语义层面进行更细致的区分。
还用你题目中的例子作分析:
智能机和 PSP 都能玩游戏。这个“玩游戏”应看作是一种功能,所以抽象为接口。而“智能机”和“PSP”本身更像“实体”的概念,应被抽象为类。
这样,“智能机类” 继承自“手机类”并实现“玩游戏接口”。而“PSP类”也可以实现“玩游戏接口”,同时完全不属于手机的概念,它可以继承自“掌机类”之类的。 这看起来要合理多了。
添加回答
举报