OberonCore https://forum.oberoncore.ru/ |
|
Перегрузка методов https://forum.oberoncore.ru/viewtopic.php?f=1&t=5374 |
Страница 1 из 1 |
Автор: | Kemet [ Суббота, 28 Март, 2015 19:29 ] |
Заголовок сообщения: | Перегрузка методов |
Зачем в КП ввели перегрузку методов? Какие проблемы решаются таким образом? |
Автор: | Илья Ермаков [ Суббота, 28 Март, 2015 20:05 ] |
Заголовок сообщения: | Re: Перегрузка методов |
Вы имеете в виду, когда B extend A, у А есть неабстрактный Do, и я в B могу его переопределить (ну и делать супервызов A.Do^)? |
Автор: | Kemet [ Суббота, 28 Март, 2015 21:21 ] |
Заголовок сообщения: | Re: Перегрузка методов |
Я имею ввиду модификатор NEW. В Оберонах( и в Модуле 3, кстати ) все методы - виртуальные, поэтому в наследнике эти методы переопределяются, т.е. в виртуальной таблице методов наследника перезаписывается тот же самый слот, такое проведение называется OVERRIDE. Модификатор же NEW позволяет создать в наследнике метод с таким же именем, но с другой сигнатурой, для этого в VMT создается новый слот. Это, по сути, и есть механизм перегрузки методов - OVERLOAD |
Автор: | Пётр Кушнир [ Суббота, 28 Март, 2015 23:21 ] |
Заголовок сообщения: | Re: Перегрузка методов |
NEW обозначает только то, что метод появился в этом рекорде, а не в предке. Для заужения результата метода не нужен NEW. Цитата: If a method M is bound to a type T0, it is implicitly also bound to any type T1 which is an extension of T0. However, if a method M' (with the same name as M) is declared to be bound to T1, this overrides the binding of M to T1. M' is considered a redefinition of M for T1. The formal parameters of M and M' must match, except if M is a function returning a pointer type. In the latter case, the function result type of M' must be an extension of the function result type of M (covariance) (see App. A). If M and T1 are exported (see Chapter 4) M' must be exported too. Вот тут компилер не позволил мне поставить NEW для B.New Код: MODULE PrivMeth;
TYPE A = EXTENSIBLE RECORD END; B = RECORD (A) END; ResultA = POINTER TO ABSTRACT RECORD END; ResultB = POINTER TO ABSTRACT RECORD(ResultA) END; PROCEDURE (VAR a: A) New(): ResultA, NEW, EXTENSIBLE; BEGIN RETURN NIL; END New; PROCEDURE (VAR b: B) New(): ResultB; BEGIN RETURN NIL; END New; END PrivMeth. |
Автор: | Kemet [ Суббота, 28 Март, 2015 23:50 ] |
Заголовок сообщения: | Re: Перегрузка методов |
Пётр, иностранными буквами написано ровно то же самое, что я писал русскими - если мы в производном типе определяем метод с той же самой сигнатурой(тип результата производного метода может быть производным типом от типа результата метода базового типа), то такой механизм называется OVERRIDE. А NEW позволяет определить в производном типе метод с тем же именем, но с другой сигнатурой, сохраняя метод предка. В твоём примере сигнатура методов совпадает, поэтому нельзя поставить NEW, т.е. нельзя перегрузить такие методы, потому что появится неоднозначность |
Автор: | Пётр Кушнир [ Воскресенье, 29 Март, 2015 02:12 ] |
Заголовок сообщения: | Re: Перегрузка методов |
Ну так New(n: INTEGER), NEW тоже не прокатывает. |
Автор: | Илья Ермаков [ Воскресенье, 29 Март, 2015 05:52 ] |
Заголовок сообщения: | Re: Перегрузка методов |
Kemet писал(а): Модификатор же NEW позволяет создать в наследнике метод с таким же именем, но с другой сигнатурой, для этого в VMT создается новый слот. Это, по сути, и есть механизм перегрузки методов - OVERLOAD Так это в КП не разрешено. Ну или может сработать для случая, когда метод в базовом классе неэкспортирован (т.е. никакой перезгрузки не будет - нет такого пространства имён, где были бы доступны оба метода). NEW введён не для перегрузки, а для предотвращения следующей ситуации, от которой нет защиты в других языках: разработчик компонента B ввёл впервые в своём расщирении метод X, потом разработчик компонента А (может быть, ничего и не знающий про B) ввел в базовом типе метод с таким же названием. При совместном использовании этих двух компонентов никто не заметит, "почему поломалось". А так сразу же будет ошибка при загрузке модулей, а далее разработчик B полезет перекомпилировать - и наткнётся на ошибку компиляции, т.к. у него X, NEW, а в базовом типе уже есть X. Вообще, в компонентной идеологии не только перезгрузка, но и OVERRIDE не приветствуется. Вообще наследование реализации практически не используется. Только от ABSTRACT. Где-то в архитектурной справке в ББ OVERRIDE и супервызовы отмечены как устаревающие, помнится. Сами разработчики ББ для случая, когда есть наследование реализации и нужна модификация поведения метода, используют следующее: Код: PROCEDURE (a: A) Do2-, NEW, EMPTY; PROCEDURE (a: A) Do, NEW; BEGIN что-то делаем свое; a.Do2 (* даём поработать типу-расширению *) END Do; Тип B(A), если нужно модифицировать Do, реализует Do2. Do2 вызывать никто не может, кроме модуля, где определён тип-хозяин A (она с -, "только для реализации"). Основное преимущество: командует парадом базовый тип. Он может дать поработать наследнику до своих действий, после или в середине. Без его ведома никто не OVERRID-ит методы. В общем, EXTENSIBLE для процедур нигде уже не применяется (есть пара мест в ББ, которые самые древние - ещё когда он был на Обероне-2). EXTENSIBLE для типов тоже крайне редко применяется, типы даже и с некоторыми реализованными методами обычно имеют достаточно много ABSTRACT-методов, т.е. таки получаются ABSTRACT, с частичной реализацией. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |