Когда я создаю свой собственный класс Android, я использую extend
его собственный класс. Затем, когда я хочу переопределить базовый метод, я всегда вызываю super()
метод, как всегда onCreate
, onStop
и т. Д.
И я подумал, что это все, так как с самого начала команда Android посоветовала нам всегда вызывать super
переопределение каждого метода.
Но во многих книгах я вижу, что разработчики, более опытные, чем я, часто пропускают звонки, super
и я действительно сомневаюсь, что они делают это из-за недостатка знаний. Например, посмотрите на этот базовый класс синтаксического анализатора SAX, в котором super
отсутствует startElement
, characters
и endElement
:
public class SAXParser extends DefaultHandler{
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase("XXY")) {
//do something
}
}
public void characters(char[] ch, int start, int length) throws SAXException {
//do something
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equalsIgnoreCase("XXY")) {
//do something
}else () {
//do something
}
}
}
Если вы попытаетесь создать какой-либо метод переопределения через Eclipse или любую другую IDE, super
он всегда будет создан как часть автоматизированного процесса.
Это был простой пример. Книги полны подобного кода .
Как они узнают, когда нужно позвонить, super
а когда можно не звонить?
PS. Не привязывайтесь к этому конкретному примеру. Это был просто случай, выбранный из множества примеров.
(Это может показаться вопросом новичка, но я действительно сбит с толку.)
источник
endElement
В документе API говорится: «По умолчанию ничего не делать. Авторы приложений могут переопределить этот метод ...», что означает, что вы можете безопасно вызывать super, потому что он «ничего не делает», но вам это не нужно, и вы действительно можете переопределить его. Часто вы можете определить, нужно ли / можно или не следует этого делать, если вы прочитаете документацию по этому методу.Ответы:
Вызывая
super
метод, вы не переопределяете поведение метода, вы его расширяете .Вызов
super
будет выполнять любую логику, которую расширяемый класс определил для этого метода. Учтите, что это может быть важным моментом, когда вы вызываетеsuper
реализацию в переопределении вашего метода. Например:Вызов to
B.save()
будет выполнятьsave()
логику для обоихA
иB
в этом конкретном порядке. Если бы ты не звонилsuper.save()
внутрьB.save()
, тебяA.save()
бы не позвонили. И если вы позвонитеsuper.save()
позжеsave(b)
,A.save()
будет эффективно выполнено послеB.save()
.Если вы хотите переопределить
super
поведение (то есть полностью игнорировать его реализацию и предоставить все самостоятельно), вам не следует звонитьsuper
.В
SAXParser
примере вы предоставите, реализации изDefaultHandler
за эти методы являются просто пустыми, так что подклассы могут переопределить их и обеспечить поведение для этих методов. В javadoc для этого метода это также указано.Что
super()
касается вызова по умолчанию в коде, сгенерированном IDE, как@barsju
указано в его комментарии, в каждом конструкторе есть неявный вызовsuper()
(даже если вы не пишете его в своем коде), что означает, в этом контексте, вызовsuper
' конструктор по умолчанию. ОнIDE
просто записывает его для вас, но он также будет вызван, если вы его удалите. Также обратите внимание, что при реализации конструкторовsuper()
или любых его вариантов с аргументами (т.е.super(x,y,z)
) можно вызывать только в самом начале метода.источник
super()
(конструктор суперкласса по умолчанию) вызывается всегда, даже если вы его не указываете. Если суперкласс не имеет конструктора по умолчанию, вы получите ошибку компиляции, если вы явно не вызовете один из конструкторов суперкласса в качестве первого оператора в конструкторе подкласса.Обычно, если специальный метод API имеет решающее значение для жизненного цикла базового контекста фреймворка, он всегда будет явно указан и выделен в документации API, например в
Activity.onCreate()
документации API . Более того, если API соответствует надежной конструкции, он должен выдавать некоторые исключения, чтобы предупредить разработчика-потребителя во время компиляции проекта и убедиться, что он не вызовет ошибку во время выполнения.Если это явно не указано в документации API, то для разработчика-потребителя вполне безопасно предположить, что метод API не является обязательным для вызова при его переопределении. Разработчик-потребитель должен решить, использовать ли поведение по умолчанию (вызвать
super
метод) или полностью переопределить его.Если условие разрешено (я люблю программное обеспечение с открытым исходным кодом), разработчик-потребитель всегда может проверить исходный код API и увидеть, как метод фактически написан под капотом. Проверьте
Activity.onCreate()
источник иDefaultHandler.startElement()
источник, например.источник
Тест, который вы должны провести в своей голове, следующий:
«Я хочу, чтобы все функции этого метода были выполнены за меня, а потом что-то делать?» Если да, то вы хотите позвонить
super()
, а затем завершить свой метод. Это будет верно для «важных» методов, таких какonDraw()
, который обрабатывает множество вещей в фоновом режиме.Если вам нужна только часть функций (как и в случае с большинством методов, которые вы переопределите), вы, вероятно, не захотите вызывать
super()
.источник
Что ж, Хави дал лучший ответ ... но вы, вероятно, знаете, что делает
super()
, когда вызывается в переопределенном методе ... он показывает, что вы сделали с поведением по умолчанию ...например:
метод в классе представления при переопределении ... вы рисуете что-то, прежде чем сказать super.onDraw (), он появляется, когда представление полностью нарисовано ... поэтому здесь вызов
super
необходим, поскольку у Android есть некоторые критически важные вещи (например, onCreate ())но в то же время
когда вы переопределяете это, вы не хотите называть super, потому что он вызывает диалоговое окно со списком параметров для EditText или любого другого аналогичного представления .. Это базовое отличие .. у вас есть выбор, чтобы оставить его несколько раз .. но для другие методы, такие как
onCreate() , onStop()
вы, должны позволить ОС справиться с этим.источник
Я не понял ваш вопрос четко, но если вы спрашиваете, почему не вызвать
super
метод:Для вызова
super
метода есть причина : если в родительском классе нет конструктора с нулевым аргументом, то для него невозможно создать дочерний класс, поэтому либо вам нужно сохранить конструктор без аргументов в родительском классе, либо вам нужно для определенияsuper()
вызывающего оператора с помощьюargument(how much argument constructor you have used in super class)
в верхней части конструктора дочернего класса.Надеюсь, это поможет. Если нет, дайте мне знать.
источник
Я реализовал список массивов ограничений, например
Если вы посмотрите на код, он просто выполняет некоторую предварительную проверку, прежде чем позволить суперклассу выполнить фактическое добавление элемента в список. Это говорит об одной из двух причин переопределения метода:
источник
Для тех, кто также задавался вопросом, какие переопределенные методы из Android Framework должны вызывать,
super
и нашел этот вопрос - вот текущая подсказка от 2019 года - Android Studio 3+ скажет вам, когда вам это нужно .источник