使用子类替换未实现接口的Java类

问题描述:

例如,java.io.File只是一个具体的类。我更换它支持解决Windows快捷方式。我需要预处理构造函数参数来解析可能的.lnk文件,因为不能访问在抽象路径上执行规范化/ canonicalision /解析的FileSystem对象。预处理需要排除纯子类 - 在调用super(...)和File不可变之前不能进行预处理。所以我扩展File并使用委托,覆盖所有File的构造函数和方法(在所有构造函数中调用super(“”))。使用子类替换未实现接口的Java类

这很好,但显然不是理想的 - 如果文件更改,我不会重写任何新的方法或构造函数,这将公开基础的空抽象路径名。我错过了明显的东西吗?似乎应该有一个更简单/更好的方法。

在具体情况下,您建议在我看来,您最好使用一个单独的工厂类来做出正常化/ canonicalision /解析的决定。

然后你可以让文件成为文件。简单。

+0

你能举个例子吗? – 2008-12-11 20:10:45

+0

我可以建议http://en.wikipedia.org/wiki/Factory_method_pattern – krosenvold 2008-12-12 09:19:18

如果你真的想要的子类的路线,你可以欺骗,或在静态块到super()呼叫有放置您的清理代码的类以外的是子类构造函数的第一行要求:

public class MyFile extends File { 

    public MyFile(String path) { 

     // static blocks aren't ideal, this is just for demo purposes: 
     super(cleanPath(path)); 
    } 

    private static String cleanPath(String uncleanPath) {...} 

} 

krosenvold建议的工厂模式是另一个很好的解决方案。

+0

是的,我认为这是我所要求的答案,但krosenvold提供了明显的和更好的解决方案,我知道我很愚蠢。我实际上比工厂方法更喜欢这种风格,并且如果File有改变也不难。但是,工厂完全避免了这种类型的耦合。 – 2008-12-10 13:53:52

这很好用,但显然不是很理想 - 如果文件改变了,我不会覆盖任何新的方法或构造函数,这会暴露底层空的抽象路径名。我错过了明显的东西吗?

不,你发现了一个使用继承的问题 - 这个子类紧密地连接到超类和它的内部,所以它可能是脆弱的。这就是为什么有效的Java和其他人说,如果可能的话,你应该在继承之前支持委派。

我认为krosenvold的解决方案听起来很干净。

在我看来,krosenvold的解决方案是要走的路。

但是,如果您需要保留创建该文件的原始路径的记录,则可以实现包装类。

public class FileWrapper { 

    private File file; 
    private String path; 

    private FileWrapper(String path) { 
     this.path = path; 
     file = new File(preProcess(path)); 
    } 

    private String preProcess(String path) { 
     // process 
     return path; 
    } 

    public File getFile() { 
     return file; 
    } 

    public String getPath() { 
     return path; 
    } 
}