inheritance尽管作文?
我通过Java World中的文章阅读了有关构图的一些内容: http : //www.javaworld.com/javaworld/jw-11-1998/jw-11-techniques.html?page = 1
在该文章中,它指导了如何在不使用extends关键字的情况下进行inheritance。 我这样做。 这可以吗? 它似乎对我有用。
这是代码:
inheritance代码的例子:文章的第2页。\根据文章,它工作正常:
class Fruit { public int peel() { System.out.println("Peeling is appealing."); return 1; } } class Apple extends Fruit { } class Example1 { public static void main(String[] args) { Apple apple = new Apple(); int pieces = apple.peel(); } }
修改后,它不再是好的:
class Peel { private int peelCount; public Peel(int peelCount) { this.peelCount = peelCount; } public int getPeelCount() { return peelCount; } } class Fruit { // Return a Peel object that // results from the peeling activity. public Peel peel() { System.out.println("Peeling is appealing."); return new Peel(1); } } // Apple still compiles and works fine class Apple extends Fruit { } // This old implementation of Example1 // is broken and won't compile. class Example1 { public static void main(String[] args) { Apple apple = new Apple(); int pieces = apple.peel(); } }
现在通过组合重用:
class Fruit { // Return int number of pieces of peel that // resulted from the peeling activity. public int peel() { System.out.println("Peeling is appealing."); return 1; } } class Apple { private Fruit fruit = new Fruit(); public int peel() { return fruit.peel(); } } class Example2 { public static void main(String[] args) { Apple apple = new Apple(); int pieces = apple.peel(); } }
后来的变化:
class Peel { private int peelCount; public Peel(int peelCount) { this.peelCount = peelCount; } public int getPeelCount() { return peelCount; } } class Fruit { // Return int number of pieces of peel that // resulted from the peeling activity. public Peel peel() { System.out.println("Peeling is appealing."); return new Peel(1); } } // Apple must be changed to accomodate // the change to Fruit class Apple { private Fruit fruit = new Fruit(); public int peel() { Peel peel = fruit.peel(); return peel.getPeelCount(); } } // This old implementation of Example2 // still works fine. class Example1 { public static void main(String[] args) { Apple apple = new Apple(); int pieces = apple.peel(); } }
之后它可以通过接口执行polymorph:请参阅Javaworld第4页上的“使用接口进行设计”。我不能在此处发布其他链接。
interface Peelable { int peel(); } class Fruit { // Return int number of pieces of peel that // resulted from the peeling activity. public int peel() { System.out.println("Peeling is appealing."); return 1; } } class Apple implements Peelable { private Fruit fruit = new Fruit(); public int peel() { return fruit.peel(); } } class FoodProcessor { static void peelAnItem(Peelable item) { item.peel(); } } class Example5 { public static void main(String[] args) { Apple apple = new Apple(); FoodProcessor.peelAnItem(apple); } }
关键是inheritance,我们创建一个新的超类实例。 而不是传统的多态性。 据说使用这种方法比inheritance更好,因为inheritance被破坏了。
编辑:稍后,如果我们希望水果变成不同类型而不是Apple,我们可以这样做:
class Banana implements Peelable { private Fruit fruit = new Fruit(); public int peel() { return fruit.peel(); } }
这就是多态性是如何通过组合完成的。 因此,如果一个方法需要一个可以剥离的水果,我们只需要将Peelable对象传递给它而不是水果。
请阅读第3个答案。 我为此主题添加了更多信息。
如果你要求评论,我要说的是:
通过组合inheritance不一定更好,也不一定比通过extends
严格inheritance更糟糕。 它们完全用于不同的目的。
组合的一个好处是它允许在API中使用更有限的潜在操作集 – 例如,可以定义从LinkedList
inheritance的Stack
类,但添加push()
和pop()
方法。 但是,没有办法通过调用诸如add(elem, 4)
或get(5)
类的东西来阻止客户端代码滥用堆栈,这会绕过堆栈。 作文解决了这个问题。
但是,扩展课程也有其好处。 例如,假设您想要创建一个Stack
,但是您不希望任何整数<0。如果您要在GreaterThanZeroStack
包含一个Stack
,那么您必须包含方法push()
, pop()
, peek()
,以及正确操作所需的其他任何东西。 这会产生许多不必要的样板重复代码。 如果您向堆栈中添加另一个方法punch()
如punch()
它也会创建不必要的维护。 如果你扩展Stack
,那么你只需要覆盖一个方法 – add(Integer i)
。 此外,您现在可以将其声明为Stack
,或将其传递给接受参数Stack s
方法。 你可以用作文来做这件事吗? 不是机会。
组合和扩展有两个完全不同的目的,组合的inheritance不一定是要遵循的模式。
在您的情况下,通过扩展inheritance是正确的。 苹果是一种水果。 苹果不含水果。 如果你要向Fruit添加另一个方法,比如weight()
,那么Apple会免费获得,而对于组合,Apple必须重新实现该方法,如下所示:
public int weight(){ return fruit.weight(); }
然后每当有关重量的变化时改变它,比如它的返回类型或名称。
一个重要的考虑因素是,在构图中你会失去“is-a”关系。 复合水果的苹果不是水果,不能传递给需要水果的方法。
并不是说inheritance被破坏了,只是它被过度使用和误用了。
关于使用接口进行多态性的评论中的要点很好。 如果您完全可以控制,则可以使用界面和组合构建整个系统。 你可能最应该 – “更喜欢构图而不是inheritance”。
但是,它“更喜欢……过度”,而不是“替换……”。 在某些情况下,某些东西的合理公共接口太大而无法为所有内容编写传递包装器方法。 我可以想到我编写的GUI工具包,它有6个代表GUI系统核心部分的顶级抽象类 – 它们绝对是使用inheritance而不是接口正确设计的。 基本组件具有大约120种方法的大型公共接口。 我肯定不会想要一个接口,然后在每个单独的具体组件中实现120个包装器方法。
请看一下这篇文章: http : //www.javaworld.com/javaworld/jw-12-1998/jw-12-techniques.html
在第2页中,有一个示例解释了您无法从Java中的多个父级inheritance的钻石问题。
在本文中,作者通过接口介绍了Java中的多重inheritance。
基于此,这就是我想出的Java中的多重inheritance如何:
interface Animal{ public void getLegs(); } class Dinosour implements Animal{ int legs=4; public int getLegs(){ return this.legs; } } class Frogs implements Animal{ int legs=2; public int getLegs(){ return this.legs; } } class Frogosour implements Animal { Dinosour father = new Dinosour(); Frog mother = new Frog(); int legs; public int getLegs(){ return (father.getLegs()+mother.getLegs())/2; } }
这是多重inheritance的想法,我可以在阅读文章后提出。 你怎么看?
我在问,因为当我第一次学习编程时,它总是通过扩展来inheritance。 现在,正如我所听到的,我的同学们说赞成作文,即使在inheritance的情况下,也比使用扩展的inheritance概念更好。 因此,组合应该优于inheritance,另一个原因是它接近函数式编程。 我只想听到不同意见。