Сокрытие методов в подклассе

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

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

Допустим, у нас есть метод public void test(int a, int b) в суперклассе, но теперь я хочу метод public void test(int a) в подклассе, который вызывает функцию суперкласса, и метод из суперкласса больше не виден.

4 ответа

Можно ли скрыть методы этого суперкласса в подклассе, наследующем от этого суперкласса?

Если вы сделаете метод приватным в суперклассе, он не будет виден в подклассе (или кому-либо еще).

Однако если вам нужно, чтобы метод в базовом классе был общедоступным, нет способа скрыть его в подклассе, например, переопределив его частной реализацией. (Вы не можете "уменьшить видимость", то есть перейти от, например, публичного или защищенного к частному в подклассе.)

Лучший обходной путь, вероятно, состоит в том, чтобы переопределить метод и выдать исключение времени выполнения, такое как UnsupportedOperationException,

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

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

Вы не можете полностью скрыть метод от суперкласса, всегда можно вызвать, например,

  MyBase o = new MyClass();
  o.test(1, 2);

Однако вы можете переопределить метод определенным образом:

class MySuper {
  public void test(int a, int b) {; }
}

class MyClass extends MySuper {
  @Deprecated
  @Override
  public void test(int a, int b) {
    throw new UnsupportedOperationException("Do not call this method, call test(int a) instead!");
  }

  public void test(int a) { ; }
}

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

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

Так что это поведение логично. Либо перепроектируйте иерархию классов, либо создайте новый класс, если он становится слишком уродливым API.

Однако вы можете переопределить метод и

/**
 * Use <code>test(a)</code> instead.
 * @param a.
 * @param b.
 */
@Deprecated
@Override
public void test(int a, int b) {
    throw new UnsupportedOperationException("Use test(int) instead.");
}

public void test(int a) { // Overloaded method
    int b = ...;
    super.test(a, b);
}

Возможна перегрузка метода: одно имя, разные типы параметров.

Java не поддерживает уменьшение видимости.

Есть способ сделать что-то подобное, но это сложно:

  1. Вам необходимо создать интерфейс для родительского типа. Этот интерфейс не должен иметь методы.
  2. Вы создаете другой, новый тип Delegate который реализует метод public void test(int a, int b)
  3. Вы удаляете текущий родительский тип.
  4. Вы создаете два новых типа, которые реализуют интерфейс. Один делегат вызова test(a,b) в Delegate а другой создает новый метод test(a) который в конечном итоге использует Delegate пример.

Таким образом, тип, который реализует старый код, никогда не будет виден внешнему миру (это может быть закрытый класс пакета).

Другие вопросы по тегам