2015-04-20 4 views
1
public class B extends A{ 

    public static void main(String[] args) { 
    new B().privateMethod();//no error -output B-privateMethod.Sounds like overriding 
    new B().staticMethod(); //no error -output B-StaticMethod.Sounds like overriding 
    } 

    private void privateMethod() { 
     System.out.println("B-privateMethod."); 
    } 
    static void staticMethod() { 
     System.out.println("B-StaticMethod."); 
    } 
} 


class A{ 
    private void privateMethod() { 
     System.out.println("A-privateMethod."); 
    } 
    static void staticMethod() { 
     System.out.println("A-StaticMethod."); 
    } 
} 

На R & DI найдено в случае privateMethod() - так как этот метод не был доступен на объекте класса ребенка так класс ребенка и родительский класс privateMethod() отдельный метод, и они не имеют никакого отношения, так что это не переопределяет , , но в случае staticMethod() - метод родительского класса был доступен на объекте дочернего класса, и когда мы определяем это в дочернем классе, объект дочернего класса начинает указывать на метод дочернего класса. Это похоже на переопределение метода, но нет, поскольку статический метод не переопределяет.поведение статического и частного методов при вызове direct на объекте дочернего класса звучит как переопределение?

Как обрабатывается статический метод с помощью набора java developmentement?

+0

Статические элементы не переопределены, они скрыты. новый B(). staticMethod(); => Это неправильный подход. вы заставите других полагать, что это метод экземпляра. Правильный способ вызова этого метода: B.staticMethod(); – Stultuske

ответ

1

полиморфизм не для статических методы. Статические методы вызывают с инструкциями JVM invokestatic, тогда как полиморфизм достигается с помощью invokevirtual. Вызовы статических методов определяются во время компиляции, а полиморфные методы динамически отправляются во время выполнения.

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

public static void main(String[] args) { 
    new B().privateMethod(); 
    A b = new B(); // change here. 
    b.staticMethod(); // A.staticMethod() is called here. 
} 
2
new B().privateMethod(); 

Это не переопределяет, так как B не видит частный метод().

new B().staticMethod(); 

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

Если позже вы определяете статический метод то же самое имя в B, что метод скрывает метод того же имени в A, поэтому вызов B.staticMethod() или new B().staticMethod() Теперь вызывает B «статический метод с. тем не менее, вызов A.staticMethod() еще будет вызывать A» s статический метод.

+0

Не могли бы вы рассказать о различии между методом hidding и overriding, за исключением того, что вызов статических методов определяется во время компиляции, вызванным с помощью инструкций JVM invokestatic, тогда как полиморфизм достигается во время выполнения с invokevirtual, для большей ясности. –

+0

@ dubey-thearcourtians Похоже, вы просите меня скопировать содержимое из другого ответа в мой ответ. Мне это не кажется правильным. – Eran

+0

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

0

Никогда не говорить о статической и переопределения в том же предложении.

Вся концепция переопределяемых методов заключается в динамическом связывании во время выполнения, какой метод должен быть выполнен. Рассмотрим это:

class A { void print() { out.println("A"); } 
class B extends A { void print() { out.println("B"); } 

A obj = new B(); 
obj.print(); 

Хотя переменная obj имеет тип A, он по-прежнему печатает "B".

Статические методы с другой стороны связаны во время компиляции. Это означает, что компилятор использует тип переменной (или выражение), чтобы определить, какой метод для выполнения:

class A { static void print() { out.println("A"); } 
class B extends A { static void print() { out.println("B"); } 

A obj = new B(); 
obj.print(); 

Это дает теперь «A». К сожалению, язык Java позволяет вызывать статические методы для переменных или выражений. Это не рекомендуется!Лучше вызывать статические методы на самом типе:

A.print(); 
B.print(); 

В первом примере - obj.print(); - компилятор автоматически переводит заявление в A.print(). Фактический объект не учитывается. На самом деле можно было бы написать следующее:

A obj = null; 
obj.print(); 

Или:

((A) null).print(); 

Что еще печатает "А".