Сокрытие методов в подклассе
У меня есть абстрактный суперкласс с некоторыми реализованными методами.
Можно ли скрыть методы этого суперкласса в подклассе, наследующем от этого суперкласса? Я не хочу, чтобы некоторые методы были видны из суперкласса в некоторых подклассах. И последнее, но не менее важное: возможно ли изменить количество аргументов для метода в подклассе, который имеет то же имя в суперклассе?
Допустим, у нас есть метод 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 не поддерживает уменьшение видимости.
Есть способ сделать что-то подобное, но это сложно:
- Вам необходимо создать интерфейс для родительского типа. Этот интерфейс не должен иметь методы.
- Вы создаете другой, новый тип
Delegate
который реализует методpublic void test(int a, int b)
- Вы удаляете текущий родительский тип.
- Вы создаете два новых типа, которые реализуют интерфейс. Один делегат вызова
test(a,b)
вDelegate
а другой создает новый методtest(a)
который в конечном итоге используетDelegate
пример.
Таким образом, тип, который реализует старый код, никогда не будет виден внешнему миру (это может быть закрытый класс пакета).