1

我有一个abstract class装载机:

public abstract class Loader
{
    private String EXTENSION = ".xxx";
    private String dir;

    public abstract Object load(String file);
    public abstract List<?> loadList(String file, int number);

    public Loader(String dir)
    {
        this.dir = dir.replace("\\", "/") + "/";;
    }

    public String formatName(String name) 
    {
        return dir + name + EXTENSION;
    }
}

它的子类应该能够改变 EXTENSION

public class MidiLoader extends Loader
{
    private String EXTENSION = ".mid";

    public MidiLoader(String dir)
    {
        super(dir);
    }

    public MidiLoader()
    {
        super(Constants.SOUNDDIR);
    }

    @Override
    public Sequence load(String file)
    {
        blah
    }

    public List<Sequence> loadList(String file, int number)
    {
        blah
    }

}

EXTENSION ".mid" 应该由Loader'sformatName函数使用。我如何让它做到这一点(不重复代码)?

谢谢。

4

2 回答 2

4

有一个构造函数

protected Loader(String dir, String ext)

这样扩展是由子类决定的。

顺便说一句,为抽象类创建构造函数public可能会令人困惑,因为它不能公开使用。

于 2013-05-12T21:18:05.603 回答
0

问题是您不能仅覆盖属性方法。要遵循更好的 OOP 模型,您应该使用封装并为 EXTENSION 提供 getter 和 setter。在您的 Loader 类中添加这样的内容:

 private String extension = ".xxx"

 public void setExtension(String extension) {
     this.extension = extension;
 }

 public String getExtension() {
     return this.extension;
 }


public String formatName(String name) {
    return dir + name + getExtension();
}

除非属性实际上是一个常量,否则最好使用小写名称进行扩展。然后,您还可以向 Loader 添加一些构造函数。

// Previous without using an explict extension
public Loader(String dir) {
  ...
}

public Loader(String dir, String extension)
{
   this(dir); // call the default constructor
   this.extension = extension;
}

然后在 MidiLoader 构造函数中,您可以调用 callsuper(dir,extension)

或者,您可以忽略构造函数和 setter,只在每个子类中定义 getExtension()。如果你走那条路,最好让 getExtension 抽象。

因此 Loader 将定义以下内容:

public abstract String getExtension();

抽象方法必须由子类实现,您不能实例化抽象类本身。这意味着 MidiLoader 将被迫提供一个名为 getExtension() 的方法,该方法返回一个 String 并且 formatName 将始终有效(使用我的增强 formatName 方法)。

于 2013-05-12T21:28:29.313 回答