2013-03-10 3 views
6

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

Пример:

public class Apartment{ 

    static int area = 10; 

    public static int getArea(){ 
     return area; 
    } 
} 

class BedroomFlat extends Apartment { 

    int area = 10;// no problem at all 

    public int getArea(){ // illegal line it cannot hide the super static method 
     return area; 
    } 
} 

Так что, если я попытался объявить int area (переменная экземпляра) вместе с static int area в родительском классе это дало бы ошибку, но это не происходит, когда объявлен в подклассе даже несмотря на то, static int area все еще видно из подкласса.

В чем разница в отношении поведения между попытками затенения статического метода с помощью метода экземпляра и попытки затенения статической переменной переменной экземпляра.

Заранее спасибо.

+1

Возможный дубликат [Почему Java не позволяет переопределять статические методы?] (Http://stackoverflow.com/questions/ 2223386/why-doesnt-java-allow-overriding-of-static-methods) – Makoto

+0

Я полностью понимаю, почему статические методы не переопределяются. Я хотел знать только, почему тени переменной области экземпляра (в терминах new Bedroom(). A вернет переменную экземпляра, а не суперстатическую), а для методов это не может быть – Rollerball

ответ

1

В вашем подклассе (BedroomFlat) компилятор не позволит вам объявить метод экземпляра с тем же именем, что и для статического метода в базовом классе, потому что переопределение метода применимо только к методам экземпляра. Расширение класса только делает методы экземпляра доступными для подкласса для переопределения (а не методов класса, то есть статического). Кроме того, когда вы пытаетесь объявить метод с той же сигнатурой, что и статический метод, компилятор выдаст ошибку, заявив, что вы не можете переопределить статический метод, поскольку переопределение происходит для метода instance.

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

2

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

В вашем случае вы не перекрывая getArea(); от родителей, вы пытаетесь создать метод с той же подписью - и это приводит к ошибке компиляции.

+0

Я полностью понимаю, почему статические методы не переопределяются. Я хотел знать только, почему тени переменной области экземпляра (в терминах new Bedroom(). A вернет переменную экземпляра, а не суперстатическую), а для методов это не может быть – Rollerball

0

Вещь: Вы ничего не слежка здесь вообще ...

Ваш экземпляр переменной доступен непосредственно моей именования и НОРМАЛЬНО вы должны написать что-то вроде ClassName.staticVar для доступа к статической переменной. Java позволяет только опустить имя класса при ссылке на статическую переменную.

Это дает понять, не так ли?

+0

Я знаю, почему она не компилируется. скажем, у меня новый BedreoomFlat(). getArea() компилятор не знает, какой getArea выбрать. статический или экземпляр? оба доступны таким образом. но для области переменных экземпляра нет проблемы, даже если область статической переменной видима, поэтому ее можно затенять. – Rollerball

0

В Java статические методы и поля относятся только к классу, поэтому они не могут наследоваться объектами, иначе это приведет к ошибке компиляции.

0

Мы знаем, что ребенок наследует родителя, но мы также знаем, что статические методы нельзя переопределить. Таким образом, в этом случае у вас есть два метода в дочернем элементе с той же сигнатурой метода. Это создаст проблему, поскольку java не поддерживает два метода одной и той же сигнатуры, хотя здесь один метод статический, а другой нестационар. но для статической переменной это не так.

+0

Это точка, если один метод указывает на класс, а другой метод указывает на экземпляр. почему он должен создавать конфликт? Разве это не та же логика с статической int area = 10 и int area = 10? В чем разница, почему это не так? – Rollerball

0

Я предполагаю, что это дает некоторые проблемы при полиморфизме (или, по крайней мере, как оно реализовано). Скажем, вы делаете что-то вроде этого Apartment x = new BedroomFlat();.Вызывая метод getArea(), он не знает, является ли он скрытым методом или переопределен, потому что если он скрытый (статический), он должен вызвать тот, который находится в классе Apartment, но если он переопределен, он должен вызвать экземпляр.

Конечно, обычно этих случаев следует избегать (это дает ненужные головные боли).

EDIT: Я нашел эту ссылку, где в нижней части страницы вы можете увидеть таблицу метода, скрывающую/переопределяющую между статическими и экземплярами. Idk, почему так оно и есть, но, по крайней мере, мы знаем, что он где-то написан (https://docs.oracle.com/javase/tutorial/java/IandI/override.html)

Смежные вопросы