Просмотр полной версии : Предназначение super()
Godwarlock
07.11.2015, 05:15
Всем привет. Вот встал вопрос. Объясните предназначение суперкласса в проектах? Ну и что, что он вызывает родительскую версию конструктора, но собственно для чего? Какой смысл?
В ActionScript 3, super можно вызывать в любом месте конструктора. Например
package {
public class SubClass extends SuperClass {
protected var value:int;
public function SubClass(value:int = 0) {
this.value = value;
super(20);
}
}
}
При перекрытии имеет значение. Перекрытием (overriding) называется переопределение метода в классе, который в противном случае был бы унаследован. Новый метод будет использоваться вместо унаследованного (хотя унаследованный метод остается доступен с использованием super).
caseyryan
07.11.2015, 08:49
Объясните предназначение суперкласса в проектах? Ну и что, что он вызывает родительскую версию конструктора, но собственно для чего? Какой смысл?
Когда создается свой класс, он наследуюе все свойства другого (суперкласса). Даже если не написать extends, он все равно по умолчанию будет наследовать свойства класса Object. Так вот чтобы все эти свойства суперкласса стали доступны, их тоже нужно создать. А так как класс создается вызовом конструктора, его необходимо вызвать. Если конструктор суперкласса не принимает никаких аргументов, то вызывать super() вручную не обязательно. Флеш плеер вызовет его автоматически.
В ActionScript 3, super можно вызывать в любом месте конструктора.
Не всегда. Например если поставить throw перед вызовом конструктора суперкласса, то эту конструкцию он не пропустит. Поэтому лучше всегда ставить super() первым делом. Тем более что во многих других языках, он обязательно должен быть в самом начале, не надо вырабатывать плохую привычку
не надо вырабатывать плохую привычку
Не вижу ничего плохого в том, чтобы выполнить какие-то действия перед super(), если необходимо.
caseyryan
07.11.2015, 13:24
Не вижу ничего плохого в том, чтобы выполнить какие-то действия перед super(), если необходимо.
Например? Что может быть необходимо выполнить перед вызовом super()? Уверен, что любой пример здесь будет просто пимером плохой архитектуры.
Да и, повторюсь, это невозможно сделать во многих других языках. Зачем привыкать делать не правильно?
Зачем привыкать делать не правильно?
Может быть для меня это "правильно" так как я не знаю множество других языков? :) В чем неправильность заключается в контексте AS3.0, ну или в программировании в целом, в той части которая пересекается с AS3.0?
Пример:
В суперконструкторе вызывается протектед метод init(). В наследнике в конструктор передаются параметры, которые я хочу использовать в переопределенном методе init().
Godwarlock
07.11.2015, 13:47
Всем спасибо за ответы, частично разобрался)
caseyryan
07.11.2015, 14:59
Может быть для меня это "правильно" так как я не знаю множество других языков? :) В чем неправильность заключается в контексте AS3.0, ну или в программировании в целом, в той части которая пересекается с AS3.0?
Пример:
В суперконструкторе вызывается протектед метод init(). В наследнике в конструктор передаются параметры, которые я хочу использовать в переопределенном методе init().
Вот, это как раз пример не правильной архитектуры. Сделай сеттеры для всех свойств, которые тебе нужно использовать, и назнач их через сеттеры. А что если в адоби вдруг захотят сделать "правильно" и запретят вызов метода super() после какой-то кода в коснтрускторе? Все приложения, где это есть сразу сломаются. Хотя правильно сделать можно уже сейчас.
А не правильный такой подход исходя из чистой логики. Как с домом, ты пытаешься крыть крышу, не построив стены
Не верная метафора крыша/стены. Дочерний класс строит не крышу, а вносит свои изменения и дополнения в строй материалы и методы их использования для построения этих самых стен. Крыша не является стеной, наследуюясь от стены, она бы являлось таковой. Более того, запись нескольких значений, никак не влияет на построение стен, значения относятся только к наследнику, что не расходится даже с твоей метафорой. Поэтому не убедил меня твой довод :)
А что если в адоби вдруг захотят сделать "правильно" и запретят вызов метода super() после какой-то кода в коснтрускторе? Все приложения, где это есть сразу сломаются. Хотя правильно сделать можно уже сейчас.
И тут мы плавно возвращаемся к теме, что сотона победил, флеш мертв, и приходится портировать as3 на какого-нибудь уродца на костылях. И да, по поводу правильности тоже вопросы остались.
undefined
07.11.2015, 15:32
А что если в адоби вдруг захотят сделать "правильно"
С тем же успехом адоби может вообще отказаться от обратной совместимости.Программист опасная профессия =)
caseyryan
07.11.2015, 16:34
Не верная метафора крыша/стены. Дочерний класс строит не крышу, а вносит свои изменения и дополнения в строй материалы и методы их использования для построения этих самых стен. Крыша не является стеной, наследуюясь от стены, она бы являлось таковой. Более того, запись нескольких значений, никак не влияет на построение стен, значения относятся только к наследнику, что не расходится даже с твоей метафорой. Поэтому не убедил меня твой довод :).
Ее можно трактовать так: суперкласс строит дом без крыши, в котором модно жить, а наследник добавляет ему нувые функции, например защиту от дождя в виде крыше.
Не должен подкласс создаваться раньше суперкласса. Как тебе еще такая метафора: "потомок рождается раньше предка, потому что ему нужны новые черты лица, которых у предка не было") Она сюда подходит как нельзя лучше. Даже названия те же)
С тем же успехом адоби может вообще отказаться от обратной совместимости.Программист опасная профессия =)
Это не повод делать все задом наперед)
Ты рассуждаешь о композиции, а не о наследовании. Когда кот мурзик рождается на свет, то это одно целое - кот. Он не выходит по частям: сначала появилось некое животное, а потом к нему приклеили усы и хвост. Нет это просто кот, он не рождается позже или раньше кого-то, он сам по себе. И являясь животным, при этом он обладает своими собственными свойствами и поведением, которое у "базового животного" может отличаться или отсутствовать. Поэтому кот, как целое, волен вызывать суперконструктор, исходя из своего собственного поведения. В конце концов конструктор - это тот же метод как и прочие. А если переопределив какой-то метод нам необходимо вызвать внутри этого метод супер версию, то мы обязаны, следую твоей логике, делать этот вызов исключительно вначале? Или, все же исходя из того, какое поведение тебе нужно получить?
upd: Другое дело, что до рождения кота, мы не можем его заставить ходить или мяукать, поэтому нет смысла вызывать мяу(), до того как кот будет создан, но сам процесс создания мы можем контролировать.
Zebestov
07.11.2015, 18:52
udaaff, можешь привести пример "необходимых перед вызовом super()" действий?
http://www.flasher.ru/forum/showpost.php?p=1188771&postcount=6
Zebestov
07.11.2015, 19:00
http://www.flasher.ru/forum/showpost.php?p=1188767&postcount=4
Чем тебя пример не устраивает?
Zebestov
07.11.2015, 20:04
Тем, что он какой-то нелепый. Независимо от того, что ты хочешь переопределить, все равно будет вызван super() и родительский init(). Таким образом никакой необходимости делать что-то до super() все еще не видно.
Речь идет о переопределенном методе init().
class SuperClass
{
public function SuperClass()
{
super();
init();
}
protected function init():void
{
}
}
class SubClass extends SuperClass
{
public function SubClass(param:*)
{
_param = param;
super();
}
private var _param:*;
override function init():void
{
super.init();
trace(_param);
}
}
А такой пример?
public class ConfirmWindow extends NativeWindow
{
private var _windowOptions:NativeWindowInitOptions;
public function ConfirmWindow(message:String)
{
_windowOptions = new NativeWindowInitOptions();
_windowOptions.systemChrome = NativeWindowSystemChrome.STANDARD;
_windowOptions.type = NativeWindowType.UTILITY;
_windowOptions.resizable = false;
super(_windowOptions);
//...
Zebestov
07.11.2015, 21:54
Речь идет о переопределенном методе init().Мне кажется, или при new SubClass() не будет никакого трейса?
А вот Wolsh привел хороший пример, да.
undefined
07.11.2015, 22:01
а разве можно менять сигнатуру конструктора?
Zebestov
07.11.2015, 22:02
А как бы мы иначе делали самодельный Event с data:* в конструкторе!
undefined
07.11.2015, 22:04
а ну да. Хотя я обычно пишу data в паблик секции.
udaaff, можешь привести пример "необходимых перед вызовом super()" действий?
Можно переопределить какие-нить протектед переменные, которые используются в суперконструкторе. Насколько это неправильно не знаю,но вполне сойдет за пример по-моему.
.. как бы мы делали любой наследник Спрайта с параметрами в конструкторе ;)
Мне кажется, или при new SubClass() не будет никакого трейса?
Почему тебе так кажется? )
Zebestov
08.11.2015, 04:08
Почему тебе так кажется? )Потому что супер будет вызывать непереопределенный init(). Есть подтверждение обратного?
Потому что супер будет вызывать непереопределенный init().
А переопределенный тогда кто вызывать тогда будет?
Есть подтверждение обратного?
В чем проблема две строчки кода протестировать? Тебе же кажется, мне вот не кажется, я знаю. И выводы о чем-то стараюсь делать на этом же основании, а не на основании того, что у меня где-то что-то звенит в правом ухе.
Zebestov
08.11.2015, 12:03
Переопределенный метод должен вызвать ты сам, в новом конструкторе или еще как-то. Мне это не кажется, я почти уверен :)
caseyryan
08.11.2015, 12:26
Ты рассуждаешь о композиции, а не о наследовании. Когда кот мурзик рождается на свет, то это одно целое - кот. Он не выходит по частям: сначала появилось некое животное, а потом к нему приклеили усы и хвост. Нет это просто кот, он не рождается позже или раньше кого-то, он сам по себе. И являясь животным, при этом он обладает своими собственными свойствами и поведением, которое у "базового животного" может отличаться или отсутствовать. Поэтому кот, как целое, волен вызывать суперконструктор, исходя из своего собственного поведения. В конце концов конструктор - это тот же метод как и прочие. А если переопределив какой-то метод нам необходимо вызвать внутри этого метод супер версию, то мы обязаны, следую твоей логике, делать этот вызов исключительно вначале? Или, все же исходя из того, какое поведение тебе нужно получить?
upd: Другое дело, что до рождения кота, мы не можем его заставить ходить или мяукать, поэтому нет смысла вызывать мяу(), до того как кот будет создан, но сам процесс создания мы можем контролировать.
Я тебе привел другой пример, который ты пропустил ;)
Все равно твой подход не верный. Пример Wolsh'a тоже не является доказательством правильности такого подхода. Можно вызывать super() c параметрами по умолчанию, а потом назначить все опции окна через сеттеры. В том же конструкторе. И окно сразу появится с нужным видом. Такие сеттеры должны быть, иначе это недоработка какая-то.
Кто-то сейчас по-любому подумает "зачем сначала создавать окно с видом по умолчанию, а потом его менять?" Но я отвечу так: чтобы была более чистая и правильная архитектура. В том же MVC делается часто много "лишней" работы. Зачем передавать какие-то модели, виды, котроллеры, когда можно легко все писать в одном "классе-полотенце" и по-максимуму использовать всякие глобальные переменные. Все из-за той же правильной архитектуры.
В общем, спорить у меня как-то настроения нет. Я считал и буду считать этот подход не правильным, и никто мне не докажет обратного)
Переопределенный метод должен вызвать ты сам, в новом конструкторе или еще как-то. Мне это не кажется, я почти уверен :)
http://code.tutsplus.com/tutorials/thinking-in-commands-part-1-of-2--active-3383
Что-то пришел на ум такой пример. Обрати внимание, как вызывается метод execute().
Я тебе привел другой пример, который ты пропустил
Я ознакомился с твоими примерами. На сколько я понял, ты считаешь, что такой подход пытается заставить кота мяукать до его рождения, но это не так
В общем, спорить у меня как-то настроения нет. Я считал и буду считать этот подход не правильным, и никто мне не докажет обратного)
Ну ты волен считать как тебе угодно. Но только меня интересует истина, а не чей-то субъективный, оценочный взгляд на проблемы (если только он не возвышен до истины :) ). Если тебе что-то "кажется" не правильно, ну так ради бога, от того, что ты повторишь это десять раз, объективно таковым оно не станет. Вот только "имхо" добавляй, когда говоришь, что подход неправильный, если кроме как звоном в правом ухе объяснить ты это не можешь.
А что неверно в твоем подходе, так это плодить лишние сущности без всякой на то объективной причины.
caseyryan
08.11.2015, 14:15
А что неверно в твоем подходе, так это плодить лишние сущности без всякой на то объективной причины.
Сделай конструктор без параметров и не надо будет плодить пустые сущности. Или пусть подкласс так же принимает параметры, которые передаются суперклассу.
что подход неправильный, если кроме как звоном в правом ухе объяснить ты это не можешь.
В общем, все твои посты по этому поводу сводятся не к тому правильно это или нет, а можно ли так делать или нет. Можно, в ас3, да. Правильно? Логически нет. Почему, я уже доходчиво написал.
Или ты не согласен с тем, что это просто логично, что сначала создается объект стоящий в цепочке наледования раньше?
А почему не стоит к этом привыкать, ну это субъективно. Я помимо as3 часто пишу на Java, там так сделать нельзя. Поначалу я тоже писал super() где попало в констуркторе. В джаве это сразу падало с ошибкой еще на этапе компиляции. И решил привыкнуть везде писать super() в самом начале кода. Теперь на автомате пишу это без ошибок
Переопределенный метод должен вызвать ты сам, в новом конструкторе или еще как-то. Мне это не кажется, я почти уверен
Он точно вызовется из суперкласса
п.с. В as3 этот super вообще как-то через энное место реализован
Или ты не согласен с тем, что это просто логично, что сначала создается объект стоящий в цепочке наледования раньше?
Да, я не согласен с тем, что это логично, в моем понимании концепций ооп и наследования в частности.
Как я это понимаю (имхо). Нету никакой иерархии в наследнике. Он унаследовал от своего предка (или своих предков, их может быть сколько угодно, а если тут подумать о множественном наследовании?) его свойства и методы. Это теперь свойства и методы наследника, ни кота папы или мамы, его собственные, равноправные, находящиеся на одном уровне. И у наследника может быть свой порядок инициализации, т.е. отличный от его предков. Ему не надо сначала инициировать какую-то основу в нем, он не составлен из модулей, стоящих один на другом, он одно целое. Если метод инициализации подразумевает вызов какой-то унаследованной "основы", ну так это решать исключительно наследнику, исходя из своих надобностей.
Ты приводил пример с домом как основой и навешиванием на него всяких прибамбасов. И то, что не построив дома, к нему не прилипить сигнализацию. Я же говорю о расширении (дополнении и переопределении) концепции "дом". К примеру дом->детский сад. А не дом->дом с окном и дверью. В первом случае мы же не стоим дом, которые затем превращаем в дет.сад, нет, мы сразу строим дет.сад. А вот втором да, чтобы навесить на дом ручку и бантик, нам нужно его построить, и это в моем понимании композиция.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.