Наследование против статики в Java - PullRequest
2 голосов
/ 16 ноября 2009

Я не совсем понимаю, почему статические методы могут наследоваться в Java?

Наследование похоже на наследование от базового класса, а Static принадлежит классу, а не объекту.

Итак, если Статика принадлежит Классу только почему, она распространяется на производный класс? Разве это не должно просто соответствовать классу, в котором он был определен?

Является ли Inheriting Static методами хорошей практикой программирования?

Ответы [ 6 ]

10 голосов
/ 16 ноября 2009

В Java статические методы не наследуются (или правильное слово переопределено ), но они могут быть скрыты .

Большое отличие здесь в том, что они не подвергаются полиморфизму, как метод объекта.

public class C1 {

    static public void M1() {
        System.out.println("C1.M1().");
    }

    static public void main(String ... Args) {
        M1();
    }

}

public class C2 extends C1 {

    static public void M1() {
        System.out.println("C2.M1().");
    }

    static public void main(String ... Args) {
        M1();
        C1.main(Args);
    }

}

При запуске C2.main(null) вы получите:

C2.M1().
C1.M1().

Как видите,

вызов M1() в C1.main (...) относится к M1 из C1 и

вызов M1() в C2.main (...) относится к M1 C2.

Вызов M1 (без префикса, см. Первую строку каждого main()) не подвергается полиморфизму, так как M1 в C1 не переопределяется C2.

Но вызов из C2 относится к M1 из C2, так как M1 из C2 это hide тот, что в C1.

Подробнее здесь .

РЕДАКТИРОВАТЬ: Я только что перечитал ваш вопрос и просто посмотрел часть о "хорошей практике программирования".

Как я уже говорил, статический метод не наследуется, а скрывается, поэтому он так же хорош, как и другой метод.

С точки зрения кода, это совершенно разные методы.

Пусть скажут.

C1                has static method M1.
C2 extends C1 and has static method M1.
C3 extends C2.

При вызове M1 (без префикса) из C1 вы вызываете C1.M1 (). Когда вы вызываете M1 (без префикса) из C2, вы вызываете C2.M1 (). // получить, но спрятаться Когда вы вызываете M1 (без префикса) из C3, вы вызываете C3.M1 (). // выводим и не скрываем

Чтобы указать, какой метод, используйте имя класса, например C1.M1(), C2.M1() и C3.M1() (это будет называться C2.M1()).

Таким образом, эта реализация позволяет переопределять статический метод, но только как другой метод, а не как переопределенный (или замещающий) метод.

Следовательно, это обычно ничем не отличается от, скажем, именования их по-другому, например: C1_M() и C2_M().

Итак, вы можете спросить, зачем вам эта функция? Я действительно не знаю. Возможно, позволяет более гибкое именование метода.

Но есть использование (которое может или не может быть намеренным), которое я использовал, это полиморфизм через отражение.

Поскольку вы можете вызывать и вызывать метод по имени, используя отражение, разрешение им иметь одно и то же имя приведет к полиморфизму при работе с помощью отражения.

Например (код выполнения может не работать):

String aClsName = "C1"; // "C2";
Class aCls = Class.forName(aClsName);
Method   aMth = aCls.getMethod("M1");   // M1 of C1 or C2 depends on the class name.
aMth.invoke(null);

OR

Object aObj = new C1(); // new C2();
Class aCls = aObj.getClass();
Method   aMth = aCls.getMethod("M1");   // M1 of C1 or C2 depends on the class of the object.
aMth.invoke(null);

Когда вы думаете об этом, я думаю, что Java тоже использует это (например, writeObject(...) для сериализации), так что это может быть намерено.

Итак, в заключение следует сказать, что скрытие статического метода не является хорошей практикой программирования (Eclipse также рекомендует против него), но может быть полезно в двух случаях: (1) назвать метод точным, как предполагается, и (2) полиморф это с помощью отражения.

Надеюсь, это поможет.

5 голосов
/ 16 ноября 2009

Я не совсем понимаю, почему Static методы могут быть унаследованы в Java?

Краткий ответ: статика НЕ ​​наследуется в Java. Скорее, статические члены, объявленные в классе (с учетом ограничений «доступа»), непосредственно видны в пространстве имен производных классов, если они не «скрыты» объявлениями в производном классе.

Так что если статика принадлежит классу только почему это сказывается на производный класс? Разве это не должно остаться с классом, в котором это было определено

Ручеек не является техническим термином. Но это не то, что происходит в любом случае. Статические члены класса не являются членами производного класса.

Является ли наследование статических методов хорошим практика программирования?

Вы не можете остановить это!

Только к вашему сведению, вот некоторые вопросы "хорошей практики", связанные со статикой:

  • Изменяемые статические атрибуты должны быть закрытыми и предпочтительно преобразовываться в объекты Singleton.

  • Множество статических элементов (методов или атрибутов) или даже синглетонов могут быть признаком плохого дизайна. Это, конечно, не «объектно-ориентированный путь».

  • В некоторых типах приложений (например, веб-приложения) даже объекты Singleton проблематичны.

  • Недопустимо ссылаться на статический метод obj.someStaticMethod() или this.someStaticMethod(). Либо квалифицируйте статическое имя с именем класса, либо обращайтесь к нему без квалификации.

  • (возможно) лучше квалифицировать ссылку на статическое в суперклассе; например в подклассе обратитесь к SuperClass.someStaticMethod() вместо someStaticMethod(). (Но недостатком является то, что код более многословен. Он попадает под тот же баннер, что и плюсы и минусы импорта.)

  • static final константы должны быть объявлены с полными заглавными буквами.

3 голосов
/ 16 ноября 2009

Как вы утверждаете, статический метод принадлежит классу , и, поскольку наследование описывает отношение IS-A между типами, не является основанием полагать, что подкласс наследовал бы все Члены его суперкласса?

Лично я считаю, что эта реализация имеет большой смысл!

1 голос
/ 16 ноября 2009

Для вызова метода с использованием наследования необходим один экземпляр класса.

Поскольку у статического метода нет экземпляра, определение метода присоединяется к самому классу (без динамической отправки)

Это более или менее обоснование в моих собственных словах.

Это скорее техническая проблема (с реализацией), чем языковая функция.

Что касается:

Является ли наследование статических методов хорошей практикой программирования?

Нет, это не так. Это сложно, особенно если вы работаете со структурированным языком программирования, в конечном итоге это будет иметь смысл.

Во-первых, я не особо использую статические методы.

0 голосов
/ 16 ноября 2009

Если B является подклассом A и у нас есть A a = new B(); в качестве юридического утверждения, следовательно, они относятся к одному типу, и если статический метод имеет значение A, тогда B будет иметь его, поскольку того же типа в этом отношении. Я думаю, что ваше замешательство связано с тем, что на статические методы можно ссылаться через this, создавая впечатление, что они наследуются.

Неправильно отправлять статический метод через экземпляр класса, поэтому он всегда должен быть A.staticMethod(), что также устраняет неправильное представление о наследовании, которое вы имеете, поскольку B.staticMethod() не будет ссылаться на тот же метод, что и A если скрыто / переопределено.

0 голосов
/ 16 ноября 2009
public class StaticTest extends StaticBase {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    System.out.println("Start");
    StaticTest.printIt();
}

}

класс StaticBase {

public static void printIt(){
    System.out.println("Inside bas Class");
}

}

Разве этот код не доказывает, что Static наследуется ??

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...