2009-11-16 3 views
2

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

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

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

Is Inheriting Статические методы - хорошая практика программирования?

ответ

10

В 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.

Но вызов из С2 относится к М1 С2 как М1 С2 - Скрыть тот, что в C1.

Подробнее here.

EDIT: Я только что перечитал ваш вопрос и просто просмотрю часть о «хорошей практике программирования».

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

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

Скажем.

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().

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

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

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

Например (rought код, может не работать):

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

ИЛИ

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) полиморфировать его с помощью отражения.

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

+0

Я думаю, что Статические методы унаследованы. В качестве ответа я прилагаю код ниже. Вы можете это объяснить? – Geek

+0

Существует несколько терминов, которые можно смутить здесь. наследовать, выводить, переопределять, скрывать, перегружать. В этом случае статические методы наследуются в том смысле, что вы можете использовать его в подклассе (поэтому я могу вызвать C3.M1(), и он будет вызывать C2.M1(), когда C3 не имеет M1), но в книге OOP, возможно, слово inherit также подразумевает полиморфизм, который мой ответ объясняет, что это не так для статического метода. Статический метод не позволяет переопределить, таким образом, они не подвергаются полиморфизму. Поэтому я сказал, что статические методы не наследуются в этом смысле (они могут быть получены). Это вопрос терминологии – NawaMan

2

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

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

+0

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

+2

Я вижу вашу точку зрения, но, к сожалению, вы объединяете две разные концепции. Статические методы не принадлежат ни одному * экземпляру * типа, но принадлежат к самому типу. Когда вы используете рефлексию, вы должны указать тип, чтобы найти этот статический метод, но вам не требуется предоставлять экземпляр, для которого нужно вызвать метод. –

0
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"); 
} 

}

ли этот код не доказывает, что Статика Наследуется ??

+0

Как я уже говорил, речь идет о терминологии. Если посмотреть значение «наследовать» из словаря, да, статический метод может быть унаследован. Однако в ООП слово также подразумевает полиморфизм, статические методы которого не подчиняются (отличным от объектных методов). – NawaMan

+0

@ Geek - нет, это не доказывает. Потому что это не наследование в смысле ООП. Если вы мне не верите, прочитайте спецификацию языка Java. –

5

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

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

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

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

Is Inheriting Статические методы a практика программирования?

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

Просто FYI, вот некоторые «хорошая практика» вопросы, связанные с статики:

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

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

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

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

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

  • константы должны быть объявлены с именами всех шапок.

0

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

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

1

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

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

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

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

А:

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

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

На самом деле, на самом деле я не использую много статических методов.