Intereting Posts
Менеджер Android SDK, только показывает установленный пакет Debug android: подключитесь к sqlite db на телефоне Как вы создаете TextView в макете? Android: где сохранены загруженные файлы? Активы – «изображения», «звуки» и «вебкит»? Android-приложение установлено, но не отображается на экране Совместное использование библиотеки Android между несколькими приложениями Android с использованием Gradle Org.json.JSONException: значение <! DOCTYPE типа java.lang.String не может быть преобразовано в JSONObject Android-AVD: настройки загрузки ошибок Android – PreferenceActivity – изменение цвета сводного текста CheckBoxPreference Редактирование css на странице настроек для веб-приложения на Android Функция увеличения зума внутри прокрутки Не может запускать приложение cordova на работе устройства или эмулятора Google воспроизводит повторяющийся контент Проблема упорядочивания стека событий при запуске приложения из установщика приложений Android и с главного экрана

Когда НЕ переписывать метод super () при переопределении?

Когда я создаю свой собственный пользовательский класс 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. Не связывайтесь с этим конкретным примером. Это был просто случай, случайно выбранный из многих примеров.

(Это может показаться новичком, но я действительно смущен.)

super метод super , вы не переопределяете поведение метода, вы его расширяете .

Вызов super будет выполнять любую логику, которую класс, который вы расширяете, определил для этого метода. Учтите, что это может быть важно в тот момент, когда вы называете реализацию super в своем методе переопределения. Например:

 public class A { public void save() { // Perform save logic } } public class B extends A { private Object b; @Override public void save() { super.save(); // Performs the save logic for A save(b); // Perform additional save logic } } 

Вызов B.save() будет выполнять логику save() для A и B в этом конкретном порядке. Если вы не super.save() внутри B.save() , A.save() не вызывался. И если вы вызвали super.save() после save(b) , A.save() будет эффективно выполняться после B.save() .

Если вы хотите переопределить поведение super (то есть полностью игнорировать его реализацию и предоставить все это самостоятельно), вы не должны называть super .

В приведенном SAXParser примере SAXParser реализации DefaultHandler для этих методов просто пусты, поэтому подклассы могут переопределять их и обеспечивать поведение для этих методов. В javadoc для этого метода это также указано.

 public void startElement (String uri, String localName, String qName, Attributes attributes) throws SAXException { // no op } 

О вызове super() умолчанию в коде, сгенерированном IDE, как отметил @barsju в своем комментарии, в каждом конструкторе есть неявный вызов super() (даже если вы не записываете его в свой код), что означает, В этом контексте – вызов конструктора по умолчанию super . IDE просто записывает его для вас, но его также вызывают, если вы его удалите. Также обратите внимание, что при реализации конструкторов super() или любой из его вариантов с аргументами (т. super(x,y,z) ) можно вызывать только в самом начале метода.

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

Обычно, если специальный метод API имеет критическое значение для жизненного цикла базового контекста, он всегда будет явно указан и выделен в документации API, например документации API Activity.onCreate() . Более того, если API следует за надежной конструкцией, он должен бросить некоторые исключения, чтобы предупредить разработчика-потребителя во время компиляции проекта и убедиться, что он не будет генерировать ошибку во время выполнения.

Если это явно не указано в документации API, то для разработчика-потребителя совершенно безопасно предположить, что метод API не обязательно для вызова при его переопределении. Разработчик потребителя должен решить, использовать ли поведение по умолчанию (вызвать метод super ) или полностью переопределить его.

Если условие разрешено (я люблю программное обеспечение с открытым исходным кодом), потребительский разработчик всегда может проверить исходный код API и посмотреть, как метод фактически написан под капотом. Проверьте источник Activity.onCreate() источник DefaultHandler.startElement() например.

Тестирование, которое вы должны сделать в своей голове:

«Я хочу, чтобы все функции этого метода выполнялись для меня, а затем потом что-то делать?» Если да, то вы хотите вызвать super() , а затем закончить свой метод. Это будет верно для «важных» методов, таких как onDraw() , которые обрабатывают множество вещей в фоновом режиме.

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

Ну, Хави дал лучший ответ .. но вы, вероятно, знаете, что делает super() при вызове в переопределенном методе … он рекламирует, что вы сделали с поведением по умолчанию.

например:

 onDraw() 

Метод в классе вида при переопределении .. вы рисуете что-то перед тем, как сказать super.onDraw () появляется, как только представление полностью нарисовано .. поэтому здесь вызов super необходим, так как у android есть некоторые важные важные вещи (например, onCreate ())

но в то же время

 onLongClick() 

Когда вы переопределяете это, вы не хотите называть супер, потому что он вызывает диалог со списком параметров для EditText или любого другого подобного вида. Это базовый diff .. у вас есть выбор, чтобы оставить его несколько раз .. но для Другие методы, такие как onCreate() , onStop() вы должны позволить ОС обрабатывать это.

Я не понял ваш вопрос четко, но если вы спрашиваете, почему бы не назвать метод super :

Существует причина для вызова super метода: если в родительском классе нет конструктора нулевых аргументов, невозможно создать для него дочерний класс, поэтому либо вам необходимо сохранить конструктор аргументов в родительском классе, либо вы Необходимо определить оператор super() вызывающий с argument(how much argument constructor you have used in super class) в верхней части конструктора дочернего класса.

Надеюсь, это поможет. Если нет, дайте мне знать.

Я применил список массивов ограничений, например

 public class ConstraintArrayList<T> extends ArrayList<T> { ConstraintArrayList(Constraint<T> cons) {this.cons = cons;} @Override public boolean add(T element) { if (cons.accept(element)) return super.add(element); return false; } } 

Если вы посмотрите на код, он просто выполняет некоторую предварительную проверку, прежде чем позволить супер классу выполнить фактическое добавление элемента в список. Это говорит о одной из двух кратных причин переопределения метода:

  1. Расширяемость, в которой вы хотите расширить то, что может сделать суперкласс
  2. Специфичность, в которой вы хотите добавить определенное поведение через полиморфизм, например, в общий пример царства животных в семантике перемещения, где перемещение птиц (перемещение) и движение лягушек (прыжок) зависят от каждого подкласса.