zoukankan      html  css  js  c++  java
  • 新秀翻译(一个)——Java在继承和组合

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

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


    译文:

    本文将会举例说明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()方法。



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

    1. 去掉子类的attack()方法。

      这将使子类取决于父类attack()方法的实现。假设父类中的attack()方法发生改变(这是你无法控制的),比如:父类的attack()方法使用其它的方式来实现,子类也须要跟着改变,这不是好的设计。

    2. 重写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. 何时用继承,何时用组合?

    以下两条内容,能够告诉我们怎样在继承与组合之间做出选择:

    1. 假设存在一个“是”的关系,而且一个类要对还有一个类公开全部的接口。那么继承是更好的选择
    2. 假设存在一个“有”的关系,那么首选组合。

    总之。继承和组合都有其用途,和理解他们的优缺点是非常有必要的。


    最后说一点自己的感受吧。小弟自打初中開始学英语。成绩就没好过。最好成绩也就刚及格吧。记得当年高考的时候lz的英语成绩是55分(足以加载史冊的成绩),我的英文水平有多差,大家可想而知了吧。

    后来承蒙恩师的谆谆教诲,一直没有放弃英语的学习。如今依旧每天都在学(尽管没有掌握其精髓。可是学总比不学强)。曾经遇到外国人根本张不开嘴。不知道说什么。如今好多了。之前常常跟老外一起踢球,没事瞎白话几句,感觉也挺好玩的。

    曾经看到英文的文章,直接关掉,如今也能静下心来看下去了。


    总之,学英语心态非常重要,仅仅要你不怕它,它就没什么好怕的。

    毛主席曾说过:“All the reactionaries are the Papertiger(一切反动派都是纸老虎)”。

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

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


    原文链接: Inheritance vs. Composition in Java



  • 相关阅读:
    关于同余最短路
    【水】关于 __attribute__
    题解【AtCoder
    一些简单图论问题
    浅谈简单动态规划
    关于博客园主题(美化博客园)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第47章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第46章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第45章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第44章 读书笔记(待更新)
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4650210.html
Copyright © 2011-2022 走看看