实现继承的正确方法

Proper way to achieve inheritance

我有这个摘要 class:FooAbstract,还有两个 class 扩展它:FooSingleInstanceFooMultiInstances

public abstract class FooAbstract {
    private boolean single;

    public FooAbstract(boolean single) {
        this.single = single;
    }

    public boolean isSingle() {
        return single;
    }
}

public class FooSingleInstance extends FooAbstract {
    private Bar bar;

    public FooSingleInstance(boolean single) {
        super(single);
    }

    public Bar getBar() {
        return bar;
    }
}

public class FooMultiInstances extends FooAbstract {
    private Map<String, Bar> barMap;

    public FooMultiInstances(boolean single) {
        super(single);
    }

    public Bar getBarFromKey(String key) {
        return barMap.get(key);
    }
}

我有一个方法doSomethingWithBar(FooAbstract foo):

public void doSomethingWithBar(FooAbstract foo) {
    if (foo.isSingle()) {
        Bar bar = ((FooSingleInstance) foo).getBar();
        //do something with bar
    } else {
        //some logic to get key
        Bar bar = ((FooMultiInstances) foo).getBarFromKey(key);
        //do something with bar
    }
}

代码有点实现了我想要实现的目标,但我觉得它没有遵守编码原则。有没有更好的方法来实现这个?

您可以添加:

public abstract class FooAbstract{

    // add abstract method to get bar
    public abstract Bar getBar(String key);
}

并在 FooSingleInstance 和 FooMultiInstances 中以不同方式实现它:

public class FooSingleInstance extends FooAbstract{
    private Bar bar;
    @Override
    public Bar getBar(String key) {
        return bar;
    }
}

public class FooMultiInstances extends FooAbstract{
    private Map<String, Bar> barMap;
    @Override
    public Bar getBar(String key) {
        return barMap.get(key);
    }
}

用法是:

Bar bar=foo.getBar(key);

顺便说一句,我看不出有任何理由使用 single 字段。

你为什么关心你有什么类型的Foo

使用你的 class 并添加一个 abstract 方法:

public abstract class FooAbstract {
    public abstract Bar getInstance(String key);
}

现在您可以根据需要在不同的版本中实现该方法:

public class FooSingleInstance extends FooAbstract {

    private Bar bar;      

    @Override
    public Bar getInstance(String key) {
        return bar;
    }
}
public class FooMultiInstances extends FooAbstract {

    private Map<String, Bar> barMap;

    @Override
    public Bar getInstance(String key) {
        return barMap.get(key);
    }
}

现在您需要做的就是:

public void doSomethingWithBar(FooAbstract foo) {
    final Bar bar = foo.getInstance(key);
    //do something with bar
}

现在,鉴于您的 FooAbstract 没有变量或逻辑,将其设为 interface:

可能有意义
public interface BarFactory {
    Bar getInstance(String key);
}

您可以像这样重载方法 doSomethingWithBar:

public void doSomethingWithBar(FooSingleInstance foo) {

}

public void doSomethingWithBar(FooMultiInstances foo) {

}