阅读英文的能力对于程序员来讲,是很重要的。这几年也一直在学习英文,今天心血来潮,就在网上找了一篇简短的博文翻译一下。水平通常,能力有限,还请各位看官多多指点。java
译文:
react
本文将会举例说明Java中继承和组合的概念。首先举一个继承的例子,而后展现一下如何用组合来改善继承的设计。最后归纳一下如何在它们之间作出选择。
程序员
1. 继承 app
假设咱们有一个Insect类。这个类包含两个方法:一个是move(),一个是attack()。
ide
class Insect { private int size; private String color; public Insect(int size, String color) { this.size = size; this.color = color; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void move() { System.out.println("Move"); } public void attack() { move(); //assuming an insect needs to move before attacking System.out.println("Attack"); } }
如今你想定义一个Bee类,它是Insect类型的,可是有着不一样实现的attack()方法和move()方法。咱们能够用继承来设计,以下所示:
学习
class Bee extends Insect { public Bee(int size, String color) { super(size, color); } public void move() { System.out.println("Fly"); } public void attack() { move(); super.attack(); } } public class InheritanceVSComposition { public static void main(String[] args) { Insect i = new Bee(1, "red"); i.attack(); } }
类层次结构关系图就是如此简单:ui
输出: this
Fly
Fly
Attack
"Fly"被打印了两次,表示move()被调用了两次。可是它应该被调用了一次才对。 spa
问题出在super.attack()方法上。Insect的attack()方法调用move()方法。当子类调用super.attack()时,老是会调用重写的move()方法。
翻译
咱们能够用下面的方法解决这个问题:
public void attack() { move(); System.out.println("Attack"); }
这样能保证正确的结果,由于子类再也不依赖于父类 。然而, 代码变成了一个父类的复制品。(想象一下,attack()方法远比打印一个字符串要复杂的多)这违背了软件工程复用的原则。
这个继承的设计很差,由于子类依赖父类的具体实现,若是父类发生变化,子类将被破坏。
2. 组合
与继承相反,组合能够用于这种状况。让咱们先看看使用组合的解决方法。
attack方法被抽象为一个接口。
interface Attack { public void move(); public void attack(); }
能够对Attack接口进行多种不一样的实现。
class AttackImpl implements Attack { private String move; private String attack; public AttackImpl(String move, String attack) { this.move = move; this.attack = attack; } @Override public void move() { System.out.println(move); } @Override public void attack() { move(); System.out.println(attack); } }
将attack方法抽出来,Insect就再也不与attack相关联了。
class Insect { private int size; private String color; public Insect(int size, String color) { this.size = size; this.color = color; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } }
Bee是一个Insect的类型,它能够攻击。
// This wrapper class wrap an Attack object class Bee extends Insect implements Attack { private Attack attack; public Bee(int size, String color, Attack attack) { super(size, color); this.attack = attack; } public void move() { attack.move(); } public void attack() { attack.attack(); } }
类图:
public class InheritanceVSComposition2 { public static void main(String[] args) { Bee a = new Bee(1, "black", new AttackImpl("fly", "move")); a.attack(); // if you need another implementation of move() // there is no need to change Insect, we can quickly use new method to attack Bee b = new Bee(1, "black", new AttackImpl("fly", "sting")); b.attack(); } }
fly
move
fly
sting
3. 什么时候用继承,什么时候用组合?
下面两条内容,能够告诉咱们如何在继承与组合之间作出选择:
总之,继承和组合都有其用途,和理解他们的优缺点是颇有必要的。
最后说一点本身的感觉吧,小弟自打初中开始学英语,成绩就没好过,最好成绩也就刚及格吧。记得当年高考的时候lz的英语成绩是55分(足以载入史册的成绩),个人英文水平有多差,你们可想而知了吧。后来承蒙恩师的谆谆教诲,一直没有放弃英语的学习,如今依然天天都在学(虽然没有掌握其精髓,可是学总比不学强)。之前遇到外国人根本张不开嘴,不知道说什么,如今好多了,以前常常跟老外一块儿踢球,没事瞎白话几句,感受也挺好玩的。之前看到英文的文章,直接关掉,如今也能静下心来看下去了。
总之,学英语心态很重要,只要你不怕它,它就没什么好怕的。毛主席曾说过:“All the reactionaries are the Papertiger(一切反动派都是纸老虎)”。英语没什么好怕的,遇到老外你就跟他瞎扯呗,最不济你俩打个平手——谁也听不懂谁说什么。还有更坏的结果吗?无论怎样咱都不会输,那你还怕啥?看英文文章、书籍看不懂,那就更不用怕了,大不了弄个词典呗,我大有道在手,还怕治不了你个小英文了。别犹豫了,上吧,少年!