Java:静态抽象(再次)-最佳实践如何变通 [英] Java: static abstract (again) - best practice how to work around

查看:104
本文介绍了Java:静态抽象(再次)-最佳实践如何变通的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从理论上理解了为什么Java中没有 抽象静态 的要点,例如为什么Java中的静态方法不能抽象化

I theoretically understand the point why there is no abstract static in Java, as explained for instance in Why can't static methods be abstract in Java .

但是我该如何解决这个问题呢?

我的应用程序使用几种类型的文件,因此我希望为其分配静态属性,例如该文件类型的说明(如数据文件,另一个为配置文件,等等)。
显然,我会将其放入一个静态String中,以便可以在不实例化文件的情况下访问该描述(对GUI f.i.有用)。
另一方面,显然所有文件类型都应具有一些常见的方法,例如 getStatus(),显然我想从一个常见的超类<$ c $继承该方法c> MyFileType 。

My application uses files of a few types, which I want to assign static properties like a description of that file type (like "data file", the other being "config file", etc.). Obviously, I would put that into a static String so that the description is accessible without instancing a file (useful for the GUI f.i.). On the other hand, obviously all file types should have some common methods like getStatus(), which obviously I want to inherit from a common superclass MyFileType.

getDescription()当然在超类中是抽象的

getDescription() would of course be abstract in the superclass.

尝试使用超类和接口的组合,但是存在类似的问题:不允许抽象方法的静态实现。

Tried using a combination of a superclass and an interface, but similar problem: A static implementation of an abstract method is not allowed.

Java专家将如何解决这个问题?
我真的想创建一个如此糟糕的实现吗?

How would a Java guru solve this? Is it really such a bad implementation that I want to create?

非常感谢,
Philipp

Many thanks, Philipp

推荐答案

要重述此问题:您希望每个文件类型的类具有有关该类型的静态可用信息(例如,名称和描述)。

To restate the problem: you want your per-file-type classes to have statically available information on the type (e.g., name and description).

我们可以轻松解决问题:为您的类型信息创建一个单独的类,并在每个文件中都有一个静态实例(适当实例化),

We can easily get part-way there: create a separate class for your type info, and have a static instance of this (appropriately instantiated) in each per-file-type class.

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;
    }
}

,然后说:

package myFileAPI;

public class TextFile {
    public static final TypeInfo typeInfo
                   = new TypeInfo("Text", "Contains text.");
}

然后您可以执行以下操作:

Then you can do stuff like:

System.out.println(TextFile.typeInfo.name);

(当然,您也可以在 TypeInfo 封装底层字符串。)

(Of course, you could also use getters in TypeInfo to encapsulate the underlying strings.)

但是,正如您所说的,我们真正想要的是强制存在编译时,所有按文件类型的类中的签名静态方法 ,但是显而易见的设计路径导致在公共超类中要求使用抽象静态方法,这是不允许的。

However, as you said, what we really want is to enforce the existence of a particular signature static method in all your per-file-type classes at compile time, but the 'obvious' design path leads to requiring an abstract static method in a common superclass which isn't allowed.

我们可以在运行时强制执行 ,这可能足以确保其正确编码。我们引入文件超类:

We can enforce this at run-time though, which may be good enough to ensure it is coded correctly. We introduce a File superclass:

package myFileAPI;

public abstract class File {

    public static TypeInfo getTypeInfo() {
        throw new IllegalStateException(
                    "Type info hasn't been set up in the subclass");
    }

}

如果 TextFile 现在扩展了文件,我们在调用 TextFile.getTypeInfo()时会遇到此异常。在运行时,除非TextFile具有相同的签名方法。

If TextFile now extends File, we will get this exception when calling TextFile.getTypeInfo() at runtime, unless TextFile has a same-signature method.

这非常隐蔽:使用 TextFile.getTypeInfo进行编码()仍然可以编译,即使TextFile中没有这样的方法。即使在编译时绑定了静态方法,编译器仍然可以通过类层次结构来确定编译时静态调用目标

This is quite subtle: code with TextFile.getTypeInfo() in still compiles, even when there is no such method in TextFile. Even though static methods are bound at compile time, the compiler can still look through the class hierarchy to determine the compile-time static call target.

因此,我们需要以下代码:

So, we need code like:

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;
    }

}

请注意,我们仍然 shadowing 超类方法,因此 File.getTypeInfo()仍然可以被无意义地调用。

Note that we are still shadowing the superclass method, and so File.getTypeInfo() can still be 'meaninglessly' called.

这篇关于Java:静态抽象(再次)-最佳实践如何变通的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆