我一直致力于一项涉及代表一般动物的抽象类的赋值,其中包含cat,dog,reptile等的子类。超类具有抽象方法,每个子类实际上并未使用它们。例如,有狗和猫使用的品种和性别的存取器和变异器,但不是爬行动物类。我个人认为这是一个奇怪的设置,但这是作业所要求的。
起初我试图省略未在特定子类中使用的抽象方法,但我很快发现由于抽象方法未被覆盖而导致错误。所有我必须做的就是用适当的方法来解决这个问题......
public class Reptile extends Animal
...
public void setBreed(String newBreed){}
public String getBreed(){return null;}
... ...虽然看起来有点浪费,因为它们没有被使用。这不是一个大问题,但它让我很好奇是否有替代必须覆盖给定子类中未使用的抽象方法。除此之外,当您需要覆盖抽象方法但实际上根本不会使用该方法时,是否有任何约定?
答案 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(){}
}