Уменьшение видимости статического метода

java inheritance information-hiding

1000 просмотра

4 ответа

529 Репутация автора

Я знаю, что ребенок не может уменьшить видимость нестатического метода, и я понимаю, почему это так.

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

Это действительно возможно? Если да, то как это сделать (пример кода) и почему он был введен (кажется, что он противоречит принципу уменьшения видимости интерфейса)?

Автор: infoholic_anonymous Источник Размещён: 17.11.2014 12:41

Ответы (4)


0 плюса

333 Репутация автора

Итак, я создал тривиальный тест; IntelliJ действительно отверг это ... и да, я знаю, "это инструмент ... но тот, которому я доверяю". В любом случае, я пошел в javac, который выпустил ту же ошибку:

Error:(...) java: ...Concrete.java:5: doSomethingStatic() in 
...Concrete cannot override doSomethingStatic() in 
...Base; attempting to assign weaker access privileges; was public

Исходя из этого и нашего скептицизма в целом, я предполагаю, что ошибка содержится в вашей документации.

Ниже приведен мой пример кода, я думаю, вполне определенным. Это раздражает protected.

public class Base
{
    public static void doSomethingStatic(){}
}

public class Concrete extends Base
{
    protected static void doSomethingStatic(){}
}
Автор: BrianT. Размещён: 17.11.2014 01:22

-2 плюса

271202 Репутация автора

Это может быть скрыто перегруженным объявлением в производном классе:

class Base
{
    public static void doSomethingStatic(){}
}

class Derived extends Base
{
    public static void doSomethingStatic(String arg){}
}

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

Автор: user207421 Размещён: 17.11.2014 01:29

1 плюс

529 Репутация автора

Основываясь на ценных комментариях hagubear, кажется, что автор оператора имел в виду скрыть метод, перегружая его методом, имеющим такое же объявление.

Цитирую эту ссылку :

Мы можем объявить статические методы с той же сигнатурой в подклассе, но это не считается переопределением, так как не будет никакого полиморфизма во время выполнения. (...) Если производный класс определяет статический метод с той же сигнатурой, что и статический метод в базовом классе, метод в производном классе скрывает метод в базовом классе.

Таким образом, определение метода в дочернем классе, имеющем точно такое же объявление, эффективно скрывает исходный метод в дочернем. Однако, как и в случае полей, приведение к родителю восстановит исходный доступ.

Образец кода:

public class Test {
    public static void main( String[] args ) {
        B b = new B();
        A a = b;
        b.f(); // "Access somewhat denied"
        a.f(); // "f()"
    }
}
class A { 
    public static void f() { 
         System.out.println("f()");
    }
}
class B extends A { 
    // *must* be public
    public static void f() { 
         System.out.println("Access somewhat denied");
    }
}
Автор: infoholic_anonymous Размещён: 17.11.2014 02:07

5 плюса

207201 Репутация автора

Краткий ответ: нет, это невозможно. Вы перепутали некоторую терминологию. Сокрытие не имеет ничего общего с доступностью (это то, о чем вы на самом деле спрашиваете, а не с видимостью , которая связана с областью действия и теневым копированием и обсуждается в главе 6 Спецификации языка Java (JLS) ).

Теперь ответ дольше. Термин переопределение применяется к методам экземпляра, а термин скрытие применяется к staticметодам class ( ). Из учебного раздела Java в разделе Переопределение и скрытие методов :

Различие между сокрытием статического метода и переопределением метода экземпляра имеет важные последствия:

  • Версия переопределенного метода экземпляра, который вызывается, является той из подкласса.
  • Версия скрытого статического метода, который вызывается, зависит от того, вызывается ли он из суперкласса или из подкласса.

Некоторые из других ответов здесь дают неправильные примеры о скрытии методов, поэтому давайте вернемся к JLS, на этот раз к §8.4.8 :

Методы переопределены или скрыты на подписи за подписью.

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

Обратите внимание, что вы можете определить метод в подклассе с тем же именем, что и метод в родительском классе (или в реализованном интерфейсе), но с другим числом или типом аргументов. В этом случае вы перегружаете имя метода и ничего не переопределяете и не скрываете; метод подкласса - это новый метод, в значительной степени независимый от унаследованных методов. (Существует взаимодействие, когда компилятор должен сопоставить методы с вызовами методов, но это все.)

Теперь к вашему вопросу: термины доступность и сокрытие (а также видимость ) являются независимыми понятиями в Java. Существует, как вы выразились, «принцип», что у подкласса просто нет возможности уменьшить доступность унаследованного метода. Это применимо независимо от того, перезаписываете ли вы метод экземпляра или скрываете метод класса. Из JLS §8.4.8.3 :

Модификатор доступа ( §6.6 ) метода переопределения или сокрытия должен обеспечивать как минимум такой же доступ, что и переопределенный или скрытый метод, следующим образом:

  • Если переопределенный или скрытый метод есть public, то переопределенный или скрытый метод должен быть public; в противном случае возникает ошибка времени компиляции.

  • Если переопределенный или скрытый метод есть protected, то переопределенный или скрытый метод должен быть protectedили public; в противном случае возникает ошибка времени компиляции.

  • Если переопределен или скрытый метод имеет по умолчанию (пакет) доступ, то корректирующий или скрытия метод должен не быть private; в противном случае возникает ошибка времени компиляции.

Таким образом, тот факт, что staticметод может быть скрыт, не имеет ничего общего с изменением доступности метода.

Автор: Ted Hopp Размещён: 17.11.2014 05:57
Вопросы из категории :
32x32