抽象方法实现(如果未使用)

时间:2017-08-14 11:31:09

标签: java

例如,我有一个像这样实现的抽象类:

public abstract class Animal
{
   public abstract void makeNoise();
}

我有一个儿童班,代表一种不会产生任何噪音的动物。哪个更好?

public class Turtle extends Animal
{
   // properties and methods
   public void makeNoise()
   {
     //leave it empty
   }
}

或者我应该简单地做到:public abstract void makeNoise();在Turtle里面?

7 个答案:

答案 0 :(得分:6)

最好将makeNoise()方法移出Animal,因为所有动物都不会产生噪音。因此,创建另一个接口NoiseMaker并在其中添加makeNoise方法。

public abstract class Animal {
  // animals methods
}

public interface NoiseMaker {
   void makeNoise();
}

public class Turtle extends Animal {
   // properties and methods which are applicable for turtle
}

当你想要一只像狮子一样发出噪音的动物时,你可以扩展Animal类并实现NoiseMaker,这样它就具有动物的行为以及产生噪音。

public class Lion extends Animal implements NoiseMaker {
    public void makeNoise() {
        // implementation
    }

    // other properties and methods which are applicable for turtle
}

答案 1 :(得分:3)

人们经常做的事:抛出某种异常,例如UnsupportedOperationException或类似的东西。

但是:最后你正在修复症状

重点是:扩展基类意味着基类的派生类 IS-A 对象也是如此。而且你在问:如何违反基类的公共合同

答案是:你应该这样做。干净利落。

因为如果你开始在这里抛出异常,突然之间,可能有List<Animal> animals的调用者不能在每个对象上调用makeNoise()。相反,调用者使用instanceof(这样他就可以避免在特定类上调用makeNoise()) - 或者需要try / catch。

所以真正的答案是:退后一步,改进你的模型。确保基类上的所有方法都适用于派生类。如果不是 - 可能会引入另一个层,例如abstract class NoisyAnimal extends Animal

答案 2 :(得分:2)

这是使用UnsupportedOperationException

的最佳用例

由于抽象设计,你必须实现。所以只需实现该方法并抛出UnsupportedOperationException异常。

保持动物,因为大多数动物都会发出声音:)如果你把它移到Turtle,所有的子类都必须有自己的声音方法。

答案 3 :(得分:2)

  

或者我应该简单地制作它:public abstract void makeNoise();内的Turtle

如果你这样做,Turtle是抽象的。所以问题不是哪个更好,问题是,您是否希望能够实例化Turtle

如果这样做,则必须实施该方法。

如果您对它是抽象的可以,那么将它声明为抽象并且根本不列出该方法:

public abstract class Turtle extends Animal {
}

答案 4 :(得分:1)

您可能想区分动物是否发出噪音。

的长篇大论
public abstract class Animals {}
public abstract class AnimalsNoisy extends Animals { abstract void makeNoise(); }

然后您将使用Turtle extends Animals。这种结构的优点是,如果你有一个动物清单,你不必担心,如果他们实施了makeNoise方法,或者不是。

for(AnimalsNoisy animal: ListAnimalsNoisy) { animal.makeNoise();}

答案 5 :(得分:0)

你可能会这样写,这是你想要的吗?

C.a
C.b

答案 6 :(得分:0)

这是学习如何使代码松散耦合的一个很好的例子 通过松散耦合,我的意思是,如果您决定更改或修改代码,则不会触及以前的代码。有时它被称为OPEN-CLOSE原则 首先,您必须确定代码的哪些部分经常更改 这里的方法 makingNoise()将根据您的类具有不同的实现。

这种设计可以通过以下步骤实现。

  

1)创建一个将具有makeNoise()实现的接口   方法

public interface NoiseInterface {
   public void speak();
}
  

2)为NoiseInterface创建具体实现

例如:For Fox

public class FoxSound implements NoiseInterface {

  @Override
  public void speak()
   {
      //What does the fox say ?
      Sysout("chin chin chin tin tin tin");
   }
}
  

3:提供动物类噪声接口

public abstract class Animal
{
   public NoiseInterface noiseMaker;

   public abstract void makeNoise();

}
  

4:只需在Fox Class中提供您选择的NoiseInterface类型

public class Fox extends Animal
{
   public Fox()
   {
     noiseMaker = new FoxSound();
   }
   public void makeNoise()
   {
     noiseMaker.speak();
   }
}

现在关于这个设计的惊人之处在于你永远不必担心这个设计。我会解释你是怎么做的。

  

您只需致电

Animal me = new Fox();
fox.makeNoise();

现在将来你想要让Fox静音。 您将创建一个新的接口静音

public class Mute implements NoiseInterface {

  @Override
  public void speak()
   {
      Sysout("No sound");
   }
}

只需更改Fox类构造函数中的NoiseBehavior

即可
noiseMaker = new Mute();

您可以在 OPEN-CLOSE 原则Here

上找到更多信息