
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.7] |
![]() |
|
Страницы: (117) « Первая ... 101 102 [103] 104 105 ... 116 117 ( Перейти к последнему сообщению ) |
Сообщ.
#1531
,
|
|
|
Цитата Romkin @ А зря. Потому что данный критерий является абсолютно незначимым в лобой системе оптимизации деятельости программиста. Поэтому выглядит странно... Ты слышал про разницу между "возможностью делать что-либо" и "обязательством делать что-либо"? ![]() Дык вот, повторю измусоленную фразу "в самой возможности ничего странного нет". Добавлено Цитата --Ins-- @ Ну и где тут полиморфизм? Простой пример: Дан класс TStream. В нем объявлены виртуальные методы Read и Write, которые ничего не делают. У класса есть бесконечное множество потомков - TFileStream, который позволяет писать/читать из файла, TMemoryStream, который позволяет читать/писать из памяти и т.д. Виртуальные методы в них перекрыты. Есть некий клиентский код - скажем, функция, у которой один из параметров имеет тип TStream. Эта функция, допустим, выполняет запись в поток, переданный ей в качестве параметра. Так как методы Write/Read объявлены как виртуальные, то, куда будет писать функция зависит от того, какому классу действительно принадлежит переданный ей параметр. При этом код ее от этого не зависит. Согласен ли ты с тем, что это нормальный полиморфизм? А теперь объясни, зачем клиентскому коду возможность вызывать реализацию методов класса TStream, а не перекрытых в потомках методов? Ага, теперь понял за что ты так яро сражаешься ![]() ![]() |
Сообщ.
#1532
,
|
|
|
--Ins--, предлагаю посмотреть на этот вопрос с другой стороны. Да, С++ позволяет явно вызвать перегруженный виртуальный метод как не виртуальный, но это возможно только в одном случае - если виртуальный метод в базовом классе помещен секцию public. Если разработчик поступил таким образом, значит он позволил обращение к этому коду извне. Логично? Логично. И, более того, если разработчик базового класса задал для этого метода какую-то реализацию, значит эта реализация имеет смысл при обращении к классу именно как к базовому. Таким образом, учитывая все приведенные обстоятельства, невиртуальный вызов перегруженного виртуального метода был разрешен проектировщиком класса (варианты "а, и так сойдет, авось никто не вызовет" - тут не рассматриваются, ибо детство). Ты тут говоришь про ООП. Давай посмотрим на этот вопрос с точки зрения ООП. Что может сделать разработчик, чтобы действительно ограничить доступность такого метода и обеспечить полиморфный вызов при любом раскладе? Ну, например, он может не делать открытые методы виртуальными (если они не абстрактные - но это отдельная песня). Тем самым он убивает сразу двух зайцев:
1. Он запрещает (не)преднамеренные неполиморфные вызовы виртуальных методов. 2. Он более тонко прорабатывает интерфейс класса. Ибо в данном случае интерфейс класса будет явно разделен на открытый интерфейс (для клиентов класса) и на интерфейс расширения (для производных классов), что влечет за собой только плюсы, т. к. разработчику уже не придется совмещать несовместимое. Более того, в этом случае разработчик класса имеет гораздо больше рычагов по управлению интерфейсом расширения. Он может разделить все методы на несколько групп: - Методы, которые обязаны быть перегружены, не имеют дефолтной реализации, и не могут быть вызваны из производных классов; - Методы, которые могут быть перегружены, имеют дефолтную реализацию, и не могут быть вызваны из производных классов; - Методы, которые обязаны быть перегружены, имеют дефолтную реализацию, и могут быть вызваны из производных классов; - Методы, которые могут быть перегружены, имеют дефолтную реализацию, и могут быть вызваны из производных классов; Первая группа методов будет сделана абстрактной и помещена в private-секцию, вторая - будет помещена в private-секцию, но при этом будет иметь дефолтную реализацию, третья - будет сделана абстрактной, размещена в protected-секции и иметь дефлтную реализацию, четвертая - отличается от третьей тем, что методы не абстрактные. При этом в каждом случае разработчик имеет возможность навесить дополнительные pre- post-amble-методы/действия, которые будут отвечать за обязательные действия, которые должны быть выполнены вне зависимости от того, перегружен метод в производном классе или нет. Или реализовывать более сложную логику взаимодействия открытой и защищенной частей. Вот, что такое проектирование на С++ с точки зрения ООП. Может Delphi предоставить такую свободу в проектировании интерфейса? Или я упрусь в стенку уже на этапе попытки перегрузки private-методов? Может мне Delphi позволить делать абстрактные методы с дефолтной реализацией (т. е. методы, которые требуют обязательной перегрузки, но при этом предлагают наследнику часть функционала)? Добавлено Собственно, пример кода: ![]() ![]() class Base { public: void foo() { // делаем что-то важное Foo1Impl(); // делаем еще что-то важное Foo2Impl(); // и еще что-то делаем Foo3Impl(); // и еще что-то делаем Foo4Impl(); // и опять что-то делаем } protected: virtual void Foo4Impl() {/* какая-то реализация */;} // Этот метод может быть перегружен в потомке, но этого не требуется. Метод предоставляет потомку дефолтную реализацию virtual void Foo3Impl() = 0 {/* какая-то реализация */;} // Этот метод должен быть перегружен в потомке. Метод предоставляет потомку дефолтную реализацию private: virtual void Foo2Impl() {/* какая-то реализация */;} // Этот метод может быть перегружен в потомке, но этого не требуется. Метод имеет дефолтную реализацию virtual void Foo1Impl() = 0; // Этот метод должен быть перегружен в потомке в любом случае. }; При таком раскладе я (без злобных хаков) никак не смогу вызвать виртуальные методы невиртуально. При этом я явно (в коде) специфицировал желаемое поведение наследников. Добавлено И даже если разработчик производных классов не удосужится залезть в документацию или посмотреть (отсутствующие) комментарии на класс, базовый класс и его клиенты все равно сохранят определенные гарантии корретного функционирования класса в случае его расширения, т. к. проектировщик класса явным образом об этом позаботился и в нужных местах подложил соломку. |
![]() |
Сообщ.
#1533
,
|
|
Цитата Flex Ferrum @ Ну, например, он может не делать открытые методы виртуальными (если они не абстрактные - но это отдельная песня). Как выразился бы mo3r - это рюшечки, причём некислые такие рюшечки. И ещё кто-то после этого имеет наглость плеваться на "лишние" try...catch ![]() |
Сообщ.
#1534
,
|
|
|
Цитата wind @ Как выразился бы mo3r - это рюшечки, причём некислые такие рюшечки. И ещё кто-то после этого имеет наглость плеваться на "лишние" try...catch В смысле? Где тут рюшечки то? Ты явно разделяешь контракты - на контракт с клиентом и на контракт с наследником. Или будешь пытаться в ряде случаев совместить несовместимое? |
![]() |
Сообщ.
#1535
,
|
|
Цитата Flex Ferrum @ В смысле? Где тут рюшечки то? В смысле очень много букв (писать). И крайне неочевидно для всякого, кто не мыслит на C++ (отсюда и споры). В общем, даешь аннотации в C++! ![]() |
Сообщ.
#1536
,
|
|
|
Цитата wind @ В смысле очень много букв. Ааа... Ну-ну. ![]() ![]() |
![]() |
Сообщ.
#1537
,
|
|
Цитата Flex Ferrum @ По этому мы вводим в язык новые сущности (типа override, inherits и т. п.), дабы позволить разработчику проектировать абы как, надеясь на то, что среда в нужном месте по рукам даст? Именно, ибо удобнее, проще, понятнее и т. п. И не среда, а компилятор. |
Сообщ.
#1538
,
|
|
|
Научить правильно программировать и проектировать, конечно же, значительно сложнее.
![]() |
![]() |
Сообщ.
#1539
,
|
|
Цитата Flex Ferrum @ Научить правильно программировать и проектировать, конечно же, значительно сложнее. Боюсь, тут вы не правы. Объём рюшечек, создаваемых программистом за единицу времени или для единицы компиляции никоим образом не увязан с его способностью правильно проектировать и программировать. |
Сообщ.
#1540
,
|
|
|
Тогда к чему тут крики про то, что C++ опасен? При таком раскладе - конечно же опасен. Как опасна бензопила в руках обезьяны.
![]() ![]() ![]() |
![]() |
Сообщ.
#1541
,
|
|
Цитата Flex Ferrum @ При таком раскладе - конечно же опасен. Как опасна бензопила в руках обезьяны. ![]() Цитата Flex Ferrum @ И к чему разговоры о промышленном программировании? Промышленное программирование - это стада обезьян, причём обезьян без шансов на эволюционирование. |
Сообщ.
#1542
,
|
|
|
Цитата wind @ Боюсь, тут вы не правы. Объём рюшечек, создаваемых программистом за единицу времени или для единицы компиляции никоим образом не увязан с его способностью правильно проектировать и программировать. Да ну что ты? Пока на все свои возражения в стиле: "профессионал так будет поступать только в очень малом количестве случаев, а новичок и без этого дров наломает" я получал в ответ в стиле: "а все равно, нож острый, значит можно порезаться". Таким образом, косвенно, но увязан. Тот, кто знает - как проектировать, вполне может обойтись имеющимися средствами, причем весьма виртуозно. А вот тот, кто не знает, вынужден опираться исключительно на то, дадут ему по рукам или нет. Если не дадут - то и хорошо. А если дадут, то будет думать, как делать иначе. Но не раньше. ![]() Добавлено Цитата wind @ Промышленное программирование - это стада обезьян, причём обезьян без шансов на эволюционирование. Ааааа... Ну да, я забыл - coding for money. Чем больше строчек написал, тем больше денюжек получил. В этом случае, конечно же, самым идеальным средством разработки были бы детские кубики... ![]() ![]() |
![]() |
Сообщ.
#1543
,
|
|
Цитата Flex Ferrum @ Таким образом, косвенно, но увязан. Никак не увязан. Если в двух языках для достижения эквивалентных результатов требуется приложить различное количество усилий (а залогом успешного применения будет различное количество знаний о языке), то эта разница никак не характеризует программистов, пишущих на этих языках, с точки зрения их умений создавать правильную архитектуру. |
Сообщ.
#1544
,
|
|
|
Цитата wind @ Никак не увязан. Если в двух языках для достижения эквивалентных результатов требуется приложить различное количество усилий (а залогом успешного применения будет различное количество знаний о языке), то эта разница никак не характеризует программистов, пишущих на этих языках с точки зрения их умений создавать правильную архитектуру. Ну тогда продемонстрируй - как именно java или delphi может мне помочь в четкой спецификации упомянутых выше контрактов? А мы посчитаем количество строчек. ![]() Добавлено Про количество усилий я не говорю. Ибо все, что я описал, укладывается в объем знаний, полученных в процессе одного из "21 одного уроков". ![]() ![]() |
![]() |
Сообщ.
#1545
,
|
|
Цитата Flex Ferrum @ Ну тогда продемонстрируй - как именно java или delphi может мне помочь в четкой спецификации упомянутых выше контрактов? На java - никак, на delphi - не знаю. Я вообще-то говорю о рюшечках, а не о возможностях этих двух языков. Например, о NVI. |