Во время сегодняшнего обзора кода мой коллега сказал что-то интересное:
prototype
полезно только тогда, когда вам нужно наследование - и когда наследование когда-либо является хорошей идеей ?
Я подумал об этом и понял, что обычно использую наследование, чтобы обойти код, который изначально был плохо спроектирован. Современный ОО-стиль предпочитает композицию, а не наследование, но я не знаю ни одного языка, который принимал бы это близко к сердцу и фактически применял его.
Существуют ли универсальные языки программирования с классами, объектами, методами, интерфейсами и т. Д., Которые запрещают наследование на основе классов? (Если такая идея не имеет смысла, почему бы и нет?)
object-oriented
programming-languages
inheritance
Бенджамин Ходжсон
источник
источник
prototype
также полезно, когда у вас есть открытые методы и свойства, которые должны быть общими для всех экземпляров. Это также полезно , потому что позволяет правильно использоватьinstanceof
оператор в JavaScript:if (foo instanceof Foo) { ...
.implements
ключевого слова и интерфейсов (в отличие от наследования состояний и поведение, введенное с использованиемextends
ключевого слова в классах, содержащих любую реализацию).new
,this
Иprototype
все слишком много минного поля для общего пользования ИМО.Ответы:
Оставляя в стороне вопрос об определении объектно-ориентированного программирования, вопрос становится одним из "существуют ли языки, которые используют только композицию и не имеют инструментов для наследования?"
Ответ на это довольно просто «да». На самом деле, нет никакого способа сделать наследование, как думают классически. Один может внедренный объект в другом объекте и продлить этот объект. Из объекта Desoriented Language ( github mirror ):
У вас есть личная структура с именем, которое является строкой. У него есть публичная функция Intro, которая возвращает имя. В структуре Woman также есть функция Intro, которая обращается к встроенной в нее стойке. И поэтому можно реализовать намерения наследования, используя только композицию.
Подробнее об этом можно узнать из учебников GoLang: Наследование и создание подклассов в Go - или его близкое сходство .
Так что да, можно иметь ОО-язык без наследования, и он существует.
В Go это называется встраиванием и дает вложенным структурам возможность доступа к встроенным полям и функциям, как если бы они были у них тоже - но это не подкласс. Философию дизайна можно найти в Go FAQ: Почему нет наследования типов?
источник
typedef
иstruct
в C ...Это очень похоже на описание VBA - Visual Basic для приложений, встроенного в Microsoft Office и других хостов с поддержкой VBA (например, AutoCAD, Sage 300 ERP и т. Д.) Или даже VB6. «A» в «Basic» означает «универсальный», так что есть часть «общего назначения».
VB6 / VBA имеет классы (и, следовательно, объекты), методы и интерфейсы - вы можете определить
ISomething
интерфейс в модуле класса следующим образом:И затем есть другой класс, который делает это:
К такому классу, не предоставляющему общедоступных членов, можно было получить доступ только через его
ISomething
интерфейс - и вполне могли существовать десятки различных реализацийISomething
, поэтому код ООП VBA вполне способен к полиморфизму, и он совершенно законен для данного класса. реализовать несколько интерфейсов тоже.Однако VB6 / VBA не разрешает наследование классов , поэтому вы не можете наследовать реализацию от другого типа, только от его интерфейса. Теперь, является ли это несчастным случаем, недостатком проекта, ударом гения или огромным безобразным упущением, открыт для дебатов; не ясно, принимает ли VB6 / VBA это близко к сердцу , но это определенно усиливает это.
Если Go не выполняет наследование классов и, тем не менее, является языком ООП , то я не понимаю, почему VB6 / VBA также нельзя считать языком ООП.
</PreemptiveResponseToVBAHatersThatWillSayItIsNotAnOOPLanguage>
источник
Вы можете заставить компилятор принудительно применять выборочное наследование с помощью частного / защищенного и современного использования методов "PImpl" или "Частная реализация".
Многие API предоставляют только те компоненты, которые вы бы хотели, чтобы пользователь унаследовал, а остальные скрывают в отдельном классе реализации. Таким образом, вы могли бы написать классы, чьи общедоступные интерфейсы, на самом деле, не наследуются, могут использоваться только через композицию объектов и принудительно компилируются Это часто хорошая практика, когда он использует компилятор для реализации намерения программного обеспечения.
Быстрый поиск закрытых функций-членов в javascript показывает, что существует аналогичный принцип, хотя любой может увидеть ваш код, если сможет его использовать: http://www.crockford.com/javascript/private.html
источник