Использование ключевого слова super или использование экземпляра суперкласса при локальном вызове методов суперкласса в методе из подкласса?
Скажем у меня есть:
class Superclass {
//fields...
methodA() {...}
methodB() {...}
...
}
class Subclass extends Superclass {
//fields...
methodA() {
// Here I need to call methods A and B from superclass:
// For this, I can use supper
super.methodA();
super.methodB();
// Or I have to instantiate the superclass and use the instance
Superclass superclass = new Superclass();
superclass.methodA();
superclass.methodB();
}
Это работает в обоих направлениях, но я хочу знать, какой из них лучше использовать. Любой из этих способов плохая техника программирования? Я надеюсь, что вы дадите мне ответ и аргументы.
4 ответа
super.methodA();
Superclass superclass = new Superclass();
superclass.methodA();
Эти два вызова метода A работают в разных экземплярах, поэтому они совершенно разные. super.methodA()
исполняет methodA
на текущий момент. superclass.methodA()
исполняет methodA
на новом экземпляре Superclass
который не связан с текущим экземпляром.
Вы бы почти всегда использовали первый вариант. Что касается второго варианта, то нет смысла создавать новый экземпляр, вызывать метод для этого экземпляра, а затем никогда больше ничего не делать с этим экземпляром.
Это совершенно другое.
super.methodA()
вызовет methodA() в левом круге, при создании нового суперкласса и вызове метода methodA() сначала создаст правый круг, а затем вызовет методы из него.
Это работает в обоих направлениях, но я хочу знать, какой из них лучше использовать.
Ну, это полностью зависит от того, чего вы пытаетесь достичь. Если вы хотите создать новый, полностью независимый экземпляр, сделайте это. Но чаще вы хотите использовать реализацию суперкласса метода, который вы переопределяете, в том же экземпляре, в котором в настоящее время выполняется переопределенный метод, и в этом случае вы будете использовать super.methodA()
,
По моему опыту, super
чаще всего используется при переопределении метода для выполнения некоторой работы, специфичной для подкласса, вызова реализации суперкласса, а затем для выполнения некоторой работы, специфичной для суперкласса. Например:
@Override public void add(Foo foo) {
doSomeSubclassSpecificValidation(foo);
super.add(foo);
doSomeSubclassSpecificBookKeeping();
}
Другими словами, даже если вы переопределяете метод, вам все еще нужно "нормальное" поведение - вы просто хотите, чтобы также выполнялся дополнительный код. Или иногда вы хотите выполнить код суперкласса условно, например, только если входные данные соответствуют определенному критерию.
Получив ответы выше, вы должны понимать, что в основном вы вызываете один и тот же метод одного и того же класса, но для двух разных объектов, поэтому все зависит от того, чего вы пытаетесь достичь (от какого объекта вы планируете вызывать эти методы). Как известно, вызовы одних и тех же методов одного и того же класса, но в разных экземплярах, не одинаковы. "Супер" объект является родителем этого "объекта", и этот суперобъект был создан неявно, когда вы создали экземпляр Subclass, так что в соответствии с вашим примером кода, оба НЕ одинаковы, но для простых случаев вывод может быть одинаковым. Поднимитесь еще на один уровень вверх и посмотрите, не выглядит ли он по-другому от кода клиента (попробуйте написать код вызова подкласса).