抽象与空方法

Abstract vs Empty method

我需要在现有摘要 class 中添加一个可选方法,该方法扩展了 50 多个 classes:

public abstract class Animal{...}

所有 classes 都没有使用此方法,但将来可能会使用。

我的 classes 之一的结构是:

public class Dog extends Animal {...}

最干净的方法是使用 abstract 方法,但它迫使我更改所有现有的 classes。

解决方法是在 abstract class:

中创建 "empty" 方法
public String getString(Map<String, Object> params){
       return "";
   }

然后在 class 扩展抽象 class.

的 es 中需要时覆盖它

有没有更好的解决办法?

有一个 "empty" 方法很好。但是为了确保它会在真正需要的地方实现,请考虑从这个方法中默认抛出一个异常:

    throw new UnsupportedOperationException();

java.util.AbstractList class:

中使用了类似的方法
public E set(int index, E element) {
    throw new UnsupportedOperationException();
}

我不禁觉得你这里有一些 architectural/design 问题,但在不了解更多的情况下,我不能肯定地说。如果 50 个 class 将继承自 Animal,但不是所有的都将使用此方法,那么我想知道它们是否真的应该继承一个共同的 class。也许您需要更高级别的 sub-classing...想想 Kingdom->Phylum->Sub-Phylum。但我的直觉告诉我这仍然不是你的正确答案。

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

public string SendMessage(Animal someAnimal) {

    string message = someAnimal.getString();

    //  Send the message

}

你可以传给它一只狗、一只猫、一只鸭嘴兽——随便什么。该函数不关心,因为它可以从其基础 class.

查询消息

因此,当您说您的动物不会执行此消息时...这意味着您将有逻辑确保只有猫和狗会调用此函数,并且鸭嘴兽的处理方式不同(或者根本没有)。这样就违背了继承的意义

一种更现代的方法是使用接口建立 "has a" 关系而不是 "is a" 关系。一个平面可能有一个 IEngine 成员,但是特定类型的引擎可以设置为 run-time,或者由平面 class 本身设置,或者如果成员是可写的,则由应用程序设置。

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

public class Cessna {
    public IEngine _engine;

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

}

您也可以直接从该接口继承...不实现 IAnimalMessage 的动物将不会实现该功能。需要这样做的动物。缺点是每只动物都必须有自己的实现,但由于您的基础 class 目前有一个没有 body 的抽象函数,我假设这是一个 non-issue。使用这种方法,您可以确定 object 是否实现了接口:

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!";
    }
}

这可能是最接近您要求的我可以建议... class那些不需要消息的人在他们这样做之前不会实现该接口,但是代码可以很容易地实现检查接口是否实现并采取相应措施。

我可以提供更多 helpful/specific 想法,但我需要更好地理解您要解决的问题。