Java 实现继承的正确途径

Java 实现继承的正确途径,java,inheritance,casting,abstract-class,Java,Inheritance,Casting,Abstract Class,我有一个抽象类:fooaxtract,还有两个扩展它的类:FooSingleInstance和foomultialinstances public abstract class FooAbstract { private boolean single; public FooAbstract(boolean single) { this.single = single; } public boolean isSingle() {

我有一个抽象类:
fooaxtract
,还有两个扩展它的类:
FooSingleInstance
foomultialinstances

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);
    }
}
这段代码实现了我的初衷,但我觉得它并没有遵循编码原则。有没有更好的方法来实现这一点?

您可以添加:

public abstract class FooAbstract{

    // add abstract method to get bar
    public abstract Bar getBar(String key);
}
并在FooSingleInstance和FooMultiInstance中以不同的方式实现它:

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);
    }
}
顺便说一句,我不认为有任何理由使用
single
字段

你为什么关心你有什么类型的
Foo
? 以您的课程为例,添加一个
摘要
方法:

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);
    }
}
现在,考虑到您的
FooAbstract
没有变量或逻辑,将其设置为
接口可能是有意义的:

public interface BarFactory {
    Bar getInstance(String key);
}

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

public void doSomethingWithBar(FooSingleInstance foo) {

}

public void doSomethingWithBar(FooMultiInstances foo) {

}

doSomethingWithBar位于哪个类中?某个外部类。当它没有任何抽象方法时,为什么要将FooAbstract作为一个抽象类。@Saurabhjunjhunghuwala,同意。我不应该把它抽象化。让你的课抽象化。虽然它不包含任何抽象方法,但它不是应该实例化的东西,抽象强制执行它。如果抽象类只包含抽象方法,那么它应该是一个接口。但是从我看到的情况来看,您使用的是抽象属性,只有当实例没有被引用为
fooaxtract
时才有效。Java的方法是在编译时连接的,而不是在运行时连接的。这对于
doSomethingWithBar(Foo-Foo)
非常有效,但是对于一些带有签名的方法
doSomething(NotBar-NotBar)
,问题仍然存在。这两个答案和@BobTheBuilder给出的答案都解决了这个问题。因为时间戳较低而接受另一个。@santosh patil但你应该考虑一下这个答案中给出的
接口
建议。
public void doSomethingWithBar(FooAbstract foo) {
    final Bar bar = foo.getInstance(key);
    //do something with bar
}
public interface BarFactory {
    Bar getInstance(String key);
}
public void doSomethingWithBar(FooSingleInstance foo) {

}

public void doSomethingWithBar(FooMultiInstances foo) {

}