Phi*_*ppp 25 java static abstract
理论上我理解Java中没有抽象静态的原因,例如为什么静态方法在Java中不是抽象的.
但是我如何解决这样的问题呢?
我的应用程序使用几种类型的文件,我想分配静态属性,如该文件类型的描述(如"数据文件",另一种是"配置文件"等).显然,我会把它放到一个静态字符串中,以便在不实例化文件的情况下访问描述(对GUI文件很有用).另一方面,显然所有文件类型都应该有一些常见的方法getStatus(),显然我想从一个共同的超类继承MyFileType.
getDescription() 当然在超类中是抽象的.
尝试使用超类和接口的组合,但类似的问题:不允许静态实现抽象方法.
Java大师将如何解决这个问题?我想创建它真的是一个糟糕的实现吗?
非常感谢,Philipp
Stu*_*ter 30
重述问题:您希望每个文件类型的类具有关于类型的静态可用信息(例如,名称和描述).
我们可以轻松地在那里获得部分:为您的类型信息创建一个单独的类,并在每个文件类型类中拥有一个静态实例(适当实例化).
package myFileAPI;
public class TypeInfo {
public final String name;
public final String description;
public TypeInfo(String name, String description) {
this.name = name;
this.description = description;
}
}
Run Code Online (Sandbox Code Playgroud)
并且说:
package myFileAPI;
public class TextFile {
public static final TypeInfo typeInfo
= new TypeInfo("Text", "Contains text.");
}
Run Code Online (Sandbox Code Playgroud)
然后你可以做的事情:
System.out.println(TextFile.typeInfo.name);
Run Code Online (Sandbox Code Playgroud)
(当然,您也可以使用getter TypeInfo来封装底层字符串.)
但是,正如您所说,我们真正想要的是在编译时在所有每个文件类型的类中强制存在特定的签名静态方法,但是"明显的"设计路径导致需要一个抽象的静态方法.常见的超类是不允许的.
我们可以在运行时强制执行此操作,这可能足以确保正确编码.我们介绍一个File超类:
package myFileAPI;
public abstract class File {
public static TypeInfo getTypeInfo() {
throw new IllegalStateException(
"Type info hasn't been set up in the subclass");
}
}
Run Code Online (Sandbox Code Playgroud)
如果TextFile现在extends File,我们将TextFile.getTypeInfo()在运行时调用时获得此异常,除非TextFile具有相同的签名方法.
这非常微妙:TextFile.getTypeInfo()即使在TextFile中没有这样的方法,仍然可以编译代码.即使静态方法在编译时被绑定,编译器仍然可以查看类层次结构以确定编译时静态调用目标.
所以,我们需要以下代码:
package myFileAPI;
public class TextFile extends File {
private static final TypeInfo typeInfo
= new TypeInfo("Text", "Contains text.");
// Shadow the superclass static method
public static TypeInfo getTypeInfo() {
return typeInfo;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我们仍在隐藏超类方法,因此仍然可以"无意义地"调用File.getTypeInfo().
这听起来是抽出软件工程基本定理的好时机:
任何问题都可以通过添加另一层间接来解决.
你在这里遇到的问题是一个文件带有多条信息 - 文件的类型,文件的描述,文件内容等等.我建议把它分成两个类 - 一个代表一个类磁盘上的具体文件及其内容,第二个是某种文件类型的抽象描述.这将允许您以多态方式处理文件类型类.例如:
public interface FileType {
String getExtension();
String getDescription();
/* ... etc. ... */
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以为您使用的每种文件类型创建子类:
public class TextFileType implements FileType {
public String getExtension() {
return ".txt";
}
public String getDescription() {
return "A plain ol' text file.";
}
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以拥有这些对象的大型存储库,这将允许您查询其属性,而无需打开该类型的文件.您还可以通过存储FileType引用将类型与您使用的每个实际文件相关联.