Вызов статического метода для данного экземпляра
В этом ответе есть этот код:
//in a main method somewhere
Super instance = new Sub();
instance.method();
//...
public class Super {
public static void method() {
System.out.println("Super");
}
}
public class Sub extends Super {
public static void method() {
System.out.println("Sub");
}
}
Это печатает Super
как и ожидалось, но у меня есть некоторый код, где дан экземпляр, я хотел бы назвать статический Sub.method()
, Одним из решений может быть:
public class Sub extends Super {
public static void sMethod() {
Super.sMethod();
System.out.println("Sub (static)");
}
public void method() {
super.method();
System.out.println("Sub (instance)");
}
}
Однако, с нетривиальными телами функций (в моем случае я проверяю, что параметр попадает в пределы, допустимые для класса), существует много повторяющегося кода. Есть хороший шаблон дизайна для решения этой проблемы? Отражение, возможно, сработает, но это похоже на последнее средство.
Думая немного больше, это лучше?
public class Sub extends Super {
public static void sMethod() {
Super.sMethod();
System.out.println("Sub (static)");
}
public void method() {
Sub.sMethod();
}
}
2 ответа
Если вы хотите вызвать метод уровня класса, вам не нужен объект, просто поместите
Subclass.method();
Для чтения ваших комментариев, я думаю, вам нужно базовое наследование объектов и подход полиморфизма.
public class Super {
public void method() {
System.out.println("Super");
}
}
public class Sub extends Super {
public void method() {
System.out.println("Sub");
}
}
//in a main method somewhere
Super instance = new Sub();
instance.method();
Теперь вы знаете, какой метод будет выполняться во время выполнения, это полиморфизм вызовов и основная функция ООП.
И если вам все еще нужен статический метод по какой-то причине в объявлении метода, вы вызываете, например,
public class SubClass extends SuperClass{
public static void method2(){
//do Something
}
@Override
public void method(){
Subclass.method2();
}
}
Статические методы не являются ОО. Это удобный способ хранить данные о классе в простых случаях, и мы все часто их используем, но по мере усложнения они становятся неуклюжими и даже невозможными.
Возможно, вам будет проще придерживаться оригинального решения. (По крайней мере, это позволяет избежать статических методов.) Но вы спросили о "хорошем шаблоне проектирования", поэтому:
Вам нужны два экземпляра двух классов, скажем, MetaSub и MetaSuper, которые имеют методы и данные, ссылающиеся на Sub или Super. Им необходимо реализовать один и тот же интерфейс (назовите его Meta), чтобы вы могли получать данные, не беспокоясь о том, что у вас есть на самом деле. Все экземпляры Super будут иметь метод getMeta
который возвращает экземпляр Meta, либо MetaSub, либо MetaSuper, поскольку оригинал является Sub или нет.
Теперь это действительно легко. Вызов getMeta
на вашем Супер объекте, затем вызовите method
метод на все, что возвращается, и все готово. Вы назвали правильный метод.
Мета-классы / интерфейсы заменяют статические методы уровня класса (и данные) реальными методами экземпляров в стиле OO. Вы можете наследовать, расширять и переопределять свободно.
Вы можете расширить это по мере необходимости, с помощью экземпляра Meta для каждого подкласса Super - и даже классов, которые не расширяют Super. И у вас могут быть интерфейсы Meta2, Meta3, ..., которые могут расширять другие или нет. Вы можете даже иметь два объекта одного класса с разными мета-объектами, если хотите. Кроме того, экземпляры Meta можно использовать для обозначения содержимого коллекций: "Эти коллекции содержат вспомогательные объекты". Это намного мощнее, чем использование идентификатора класса.
(Все, что нужно, это время. По общему признанию, это намного веселее, если вы пишете что-то новое, а не расширяете устаревшую систему.)