Чтобы переформулировать проблему: вы хотите, чтобы ваши классы для каждого типа файлов имели статически доступную информацию о типе (например, имя и описание).
Мы можем легко получить неполный путь: создать отдельный класс для информации о вашем типе и иметь статический экземпляр этого (соответствующим образом созданный) в каждом классе для каждого типа файла.
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.");
}
Затем вы можете делать такие вещи, как:
System.out.println(TextFile.typeInfo.name);
(Конечно, вы можете также использовать геттеры в 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");
}
}
Если 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;
}
}
Обратите внимание, что мы все еще shadowing метод суперкласса, и поэтому File.getTypeInfo () все еще может вызываться «бессмысленно».