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

新秀翻译(一个)——Java在继承和组合

2015-07-16 08:49 274 查看
阅读英文的程序猿的能力,这是非常重要的。过去的几年中一直在学习英语,今天心血来潮,在网上找什么鲍文简要翻译。

普通级,能力有限,看官还请大家多多指点。

译文:

本文将会举例说明Java中继承和组合的概念。首先举一个继承的样例。然后展示一下怎样用组合来改善继承的设计。最后概括一下怎样在它们之间做出选择。

1. 继承

假设我们有一个Insect类。这个类包括两个方法:一个是move()。一个是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;
}

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();
}
}


类层次结构关系图就是如此简单:



输出:

Fly
Fly
Attack


"Fly"被打印了两次,表示move()被调用了两次。可是它应该被调用了一次才对。

问题出在super.attack()方法上。Insect的attack()方法调用move()方法。当子类调用super.attack()时,总是会调用重写的move()方法。

我们能够用以下的方法解决问题:

去掉子类的attack()方法。

这将使子类取决于父类attack()方法的实现。假设父类中的attack()方法发生改变(这是你无法控制的),比如:父类的attack()方法使用其它的方式来实现,子类也须要跟着改变,这不是好的设计。
重写attack()方法,例如以下:
public void attack() {
move();
System.out.println("Attack");
}

这样能保证正确的结果,由于子类不再依赖于父类 。然而。 代码变成了一个父类的复制品。

(想象一下,attack()方法远比打印一个字符串要复杂的多)这违背了软件project复用的原则。

这个继承的设计不好,由于子类依赖父类的详细实现,假设父类发生变化。子类将被破坏。

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(一切反动派都是纸老虎)”。

英语没什么好怕的。遇到老外你就跟他瞎扯呗,最不济你俩打个平手——谁也听不懂谁说什么。

还有更坏的结果吗?无论怎样咱都不会输。那你还怕啥?看英文文章、书籍看不懂。那就更不用怕了,大不了弄个词典呗。我大有道在手,还怕治不了你个小英文了。别犹豫了,上吧,少年!

原文链接: Inheritance vs. Composition in Java
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: