抽象与空方法

时间:2017-09-08 14:27:26

标签: java override abstract-class abstract

我需要在现有的抽象类中添加一个可选方法,该方法由50多个类扩展:

public abstract class Animal{...}

所有这些类都不能使用此方法,但将来它可能会使用。

我的一个班级的结构是:

public class Dog extends Animal {...}

最简洁的方法是使用abstract方法,但它要求我更改所有现有的类。

解决方法是在abstract类中创建“空”方法:

public String getString(Map<String, Object> params){
       return "";
   }

然后在扩展抽象类的类中需要时覆盖它。

有没有更好的解决方案?

2 个答案:

答案 0 :(得分:4)

&#34;空&#34;方法很好。但为了确保它将在真正需要的地方实现,请考虑默认情况下从此方法抛出异常:

    throw new UnsupportedOperationException();

java.util.AbstractList类中使用了类似的方法:

public E set(int index, E element) {
    throw new UnsupportedOperationException();
}

答案 1 :(得分:2)

我不禁觉得你在这里有一些建筑/设计问题,但不知道更多,我不能肯定地说。如果50个类将继承自Animal,但并非所有类都将使用此方法,那么我想知道它们是否应该从一个公共类继承。也许你需要更高级别的分类......想想Kingdom->Phylum->Sub-Phylum。但我的直觉说,对你来说仍然不是正确的答案。

退一步 - 你想要完成什么?如果您将来要在这些类上实现此功能,那么您还必须更改代码以了解使用/期望这一点。继承点是允许代码在不知道它引用的对象类型的情况下引用对象的预期常见行为。在getString()示例中,您可能具有以下功能:

public string SendMessage(Animal someAnimal) {

    string message = someAnimal.getString();

    //  Send the message

}

你可以传给它一只狗,一只猫,一只鸭嘴兽 - 无论如何。该函数不关心,因为它可以从其基类查询消息。

所以当你说你的动物没有实现这个消息时...这意味着你将拥有确保只有猫和狗会调用这个功能的逻辑,而且鸭嘴兽的处理方式不同(或者不是在所有)。那种失败的继承点。

更现代的方法是使用接口建立“拥有”关系而不是“是”关系。一个平面可能有一个IEngine成员,但是特定类型的引擎可以在运行时设置,可以是平面类本身,也可以是应用程序,如果该成员是可写的。

public interface IEngine {
    string getStatus();
    string getMileage();
}

public class Cessna {
    public IEngine _engine;

    public Cessna() {
        _engine = new PropellerEngine();
    }

}

您也可以直接从该接口继承...未实现IAnimalMessage的动物不会实现该功能。那些需要做的动物。缺点是每个动物都必须有自己的实现,但由于你的基类目前有一个没有正文的抽象函数,我假设这不是问题。使用此方法,您可以确定对象是否实现了接口:

IAnimalMessage animalMessage = myPlatypus as IAnimalMessage;

//  If your playtpus doesn't implement IAnimalMessage, 
//  animalMessage will be null.
if (null != animalMessage) {
    string message = animalMessage.getString();
}


public interface IAnimalMessage {
    string getMessage();
}

public class Platypus : IAnimalMessage {
    //  Add this implementation when Platypus implements IAnimalMessage...
    //  Not needed before then
    public string getMessage() { 
        return "I'm a cowboy, howdy, howdy, howdy!";
    }
}

这可能是你所要求的最接近的我可以建议......不需要该消息的类将不会实现该接口,但代码可以轻松检查接口是否已实现并且相应地采取行动。

我可以提供更多有用/具体的想法,但我需要了解您尝试更好地解决的问题。