是否需要在Java中覆盖抽象方法?

时间:2014-10-19 03:37:27

标签: java inheritance override abstract

我一直致力于一项涉及代表一般动物的抽象类的赋值,其中包含cat,dog,reptile等的子类。超类具有抽象方法,每个子类实际上并未使用它们。例如,有狗和猫使用的品种和性别的存取器和变异器,但不是爬行动物类。我个人认为这是一个奇怪的设置,但这是作业所要求的。

起初我试图省略未在特定子类中使用的抽象方法,但我很快发现由于抽象方法未被覆盖而导致错误。所有我必须做的就是用适当的方法来解决这个问题......

public class Reptile extends Animal
...
public void setBreed(String newBreed){}  
public String getBreed(){return null;}  

... ...虽然看起来有点浪费,因为它们没有被使用。这不是一个大问题,但它让我很好奇是否有替代必须覆盖给定子类中未使用的抽象方法。除此之外,当您需要覆盖抽象方法但实际上根本不会使用该方法时,是否有任何约定?

2 个答案:

答案 0 :(得分:3)

这里有两个解决方案。

您可以拥有多个级别的抽象类。换句话说(这些是shell类和函数......即没有代码):

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

public abstract class Pet extends Animal{
  public abstract void breed();
  public abstract void gender();
}

public class Reptile extends Animal{
  public void fooMethod(){}
}
public class Cat extends Pet{ //do the same for Dog
  public void fooMethod(){}
  public void breed(){}
  public void gender(){}
}

通过这种方式,Reptile仍然可以扩展Animal,但是你知道Reptile没有品种或性别功能,所以你不必为它做任何事情。同样地,Cat和Dog也扩展了Animal,但现在他们必须覆盖品种和性别。

你的另一个解决方案是做这样的事情(两个解决方案中更糟糕的):

public class Reptile extends Animal{
  public void breed(){
    throw new UnsupportedOperationException("Don't call Reptile#breed!!");
  }
}

这个解决方案特别糟糕,因为如果你没有正确的错误处理,这个异常会一直向上传播到你的main方法,如果没有异常处理,那么一直到你的主要方法,然后程序崩溃。

我个人推荐选择A.

答案 1 :(得分:1)

@ earchengine的另一个版本的答案,添加了几个接口:

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

public class Breed {...}
public interface Bred {
  Breed breed();
}

enum Gender { ...}

public interface Gendered
  Gender gender();
}

public class Reptile extends Animal {
  public void fooMethod(){}
}

public class Cat extends Animal implements Gendered, Bred {
  public void fooMethod(){}
  public Breed breed(){}
  public Gender gender(){}
}

public class Dog extends Animal implements Gendered, Bred {
  public void fooMethod(){}
  public Breed breed(){}
  public Gender gender(){}
}