Чтобы добавлять сообщения и комментарии, .

@OCTAGRAM:
OCTAGRAM

J. Hamilton. A model for implementing an object-oriented design without language extensions
Почитал. Выходит, селекторы должны указывать на смещение внутри таблицы виртуальных методов, а эти таблицы в общем случае должны предусматривать селекторы вообще для любого метода любого класса, а то, что на самом деле там их меньше, — это оптимизация. Этот доклад ссылается на объектные модели Smalltalk и Objective-C, в которых одиночное наследование, при этом ссылка на этот доклад найдена в книге «Programming with DirectToSOM C++», где модель однозначно поддерживает множественное наследование. Однако, в принципе, понятно, как применить одно к другому. В случае Smalltalk и Objective-C объектная модель плоская, допускающая коллизии между селекторами никак не связанных между собой классов, и именно разруливанию этих ситуаций посвящён доклад. А в SOM одноимённые методы классов так конфликтовать не могут, поскольку жетоны методов функционально эквивалентны кортежу из ссылки на класс-объект и имени метода. Однако конфликт возникает в другом месте, если мы пытаемся сделать у каждого класса таблицу виртуальных методов с поиском по индексу. Любое множественное наследование приводит к тому, что на один и тот же слот в таблице виртуальных методов начинают претендовать не подозревавшие о существовании друг друга классы, у которых появился общий потомок. В этом случае можно таблицы виртуальных методов родительских классов раздвинуть так, чтобы потомки не могли конфликтовать, и уже без проблем произвести таблицу виртуальных методов наследника. Приходится попариться при создании классов, зато потом всё летает. Хотя я ещё не исследовал перемычки SOM и не знаю, как оно там было на самом деле.

@OCTAGRAM:
OCTAGRAM

Approaches to Composition and Refinement in Object-Oriented Design
MN93 shows that framework refinement (in the sense of adapting a frame-work to yield another abstract framework) is not possible under either co-variant(Eiffel) or contravariant (Modula-3) typing rules.Надо бы как-нибудь ликвидировать свою безграмотность по части ковариантного и контравариантного вот этого всего.

@OCTAGRAM:
OCTAGRAM

По результатам плотной работы с SOM обнаруживается горькая правда, что множественное наследование там не как в «Putting Metaclasses to Work», CLOS, Dylan и Python, а как в C++. Линеаризации классов, порядка разрешения методов просто нет. Можно либо вызывать только первого родителя среди тех, кто поддерживает метод, либо какого-то конкретного, либо всех, и тогда в ромбовидных диаграммах наследования кому-то будет прилетать многократно. Конструкторы, деструкторы и операция присваивания, чтоб совсем плохо не было, защищаются битовыми полями. Я их и раньше видел, но мне казалось, это связано с тем, что конструкторам может требоваться передавать управление в нестандартном порядке, а обычные методы просто вызовут, что им дал somParentResolve, и попадут куда надо. Эдак довольно солидная часть книжки становится неприменимой к имеющимся бинарникам. То, что описано в книге как то, с чем авторы имели опыт, действительно было таковым, но в общий доступ не попало:
SOM DTK v3.0 Programming Guide на странице 205 (187):
Customizing method resolution requires the use of metaclasses that override SOMClass methods. This is not recommended without use of a Cooperation Framework that guarantees correct operation of SOMobjects in conjunction with such metaclasses. SOMobjects users who require this functionality should request access to the experimental Cooperation Framework used to implement the SOMobjects Metaclass Framework. Metaclasses implemented using the Cooperation Framework may have to be reprogrammed in the future when SOMobjects introduces an officially supported Cooperation Framework.

@OCTAGRAM:
OCTAGRAM

Раздраконил свой генератор привязок до такого состояния, что уже заработала программа, использующая исключительно новые привязки. Это пример для старых привязок, а это — для новых. В старых привязках SOMObject — это указатель на запись, а все остальные классы — синонимы SOMObject, то есть, контроля типов нет. В старых привязках, чтобы узнать тип аргумента, нужно было в процедурном стиле написать ParameterDef__get_type, а вот имя аргумента объявлялось в Contained, поэтому Contained__get_name, а так как вручную мне лень синонимы везде прописывать, то только по таким именам работало. В новых привязках генератор собирает все методы класса в одну общую кучу, и всё работает достаточно очевидным образом с вызовом методов через точку. И даже атрибуты CORBA спроецировались на свойства Delphi. Поскольку в Delphi жалкое одиночное наследование, генерить список методов требуется каждый раз сначала, и именно это и делается, зато потом удобно.

Работает это посредством того хака, что создаются объекты SOM, а Delphi думает, что это объекты Delphi. Так как с точки зрения Delphi методы статические, Delphi не лезет в VMT, делает статический вызов, в нём написан код, который направит вызов в SOM, и оно там пойдёт куда надо. Ещё немного пошаманил, чтобы волшебным образом работали классовые функции. Классовые функции могут вызываться как у объектов, и тогда Delphi пытается взять из объекта VMT по нулевому смещению, а может — непосредственно у класса, и тогда берётся статический адрес VMT. Учитывая, что с точки зрения Delphi классы друг от друга не наследуются, отличить эти случаи не сложно. Нужно просто сравнить Self со своим именем, и если да, то нас вызвали через имя класса, и класс-объект нужно искать одним способом, а если нет, то нас вызвали как метод объекта, и надо ещё раз разъименовать Self, и там будет лежать указатель на класс-объект.

Немного подкрутил, чтобы в результате метода SOMObject.somGetClass учитывался метакласс. Была мысль вообще все методы метакласса спроецировать на классовые функции и процедуры, но потом посмотрел, сколько там всего в SOMClass, и решил, что не надо. Тем более, что в SOM.IR публично показан только один метакласс, SOMMSingleInstance. Но даже ради него подкрутил, чтобы у метода SOMObject.somGetClass возвращался именно указанный метакласс, а не просто SOMClass. Кстати, так получается, что с точки зрения языковой проекции метаклассы не могут так просто наследоваться. То есть, умом-то мы понимаем, что компилятор SOM гарантирует совместимость метаклассов, но вот во что это спроецировать, открытый вопрос. Если мы наследуемся от двух классов с разными метаклассами, то метакласс потомка будет заведомо принадлежать пересечению множеств потомков каждого метакласса, и что, для этого динамически создаваемого метакласса тоже создавать привязки? А там по цепочке ещё для метаклассов более высокого порядка может потребоваться автоматическое создание. Одно дело — когда движок SOM это создаёт, и другое дело — когда генерится текст. Я решил, что этого делать не нужно, а раз так, то даже, если был класс A с указанием метакласса M_A, и от него наследуется класс B, то, если B не укажет явно тот же метакласс, что и A, в его привязках будет опять обычный SOMClass.

Естественно, все методы обычного TObject не будут работать. Я эту проблему пытаюсь решить, скрывая их при помощи reintroduce в private. Только операция as портит картину. Её не спрячешь, но хотя бы заменил методами, приводящими тип вверх и вниз. Вот так, с небольшой порцией магии создаётся впечатление, что SOM в Delphi как родная. Классы, методы, свойства.

@OCTAGRAM:
OCTAGRAM

Про интерфейсы и классы:
В COM замороженность интерфейсов диктовалась техническими ограничениями, во всяком случае, это то, что на виду. Однако, если присмотреться, то даже в виртуальных машинах, сценарных языках программирования и т. п. окружениях, где технические проблемы решены, мы не можем просто взять и расширить интерфейс, так как интерфейс может быть реализован вообще каким угодно классом, и не согласованные с другими командами разработчиков расширения интерфейса сломают их классы. А вот если есть класс с реализацией по умолчанию, то этот класс можно расширять, и все довольны. Так приходим к мысли о том, что множественное наследование всё–таки нужно, а так называемое «множественное наследование только для интерфейсов» — это пыль в глаза. На самом деле нет, а звучит как будто есть.

Естественно, под множественным наследованием я не имею в виду убожество из стандарта C++.

@mabu:
mabu

Основополагающий принцип ООП: код и данные вместе. И уже к нему цепляются прочие прелести типа наследования, полиморфизма и тому подобного. Поэтому если мы имеем некий объект типа файла, кучи и так далее, с которым можно производить ряд операций, то сами боги велели на уровне реализации приписать эти операции данному объекту, то есть создать класс. Невиртуальные методы класса отличаются от обычных процедур только тем, что в них автоматически передается скрытый параметр — указатель на соответствующий объект. Теперь посмотри на API‐функции какого‐нибудь объекта, например, кучи: во все RtlHeapXXX первым параметром передается hHeap — указатель на объект. Ну и чем это отличается от ООП ? Только тем, что этот параметр прописан в API явным образом. Из этого вовсе не следует, что все RtlHeapXXX на уровне исходников реализованы в виде отдельных процедур, это запросто могут быть stdcall‐методы класса HHEAP. Вывод: на уровне машинного кода никакой разницы между процедурами и невиртуальными stdcall‐методами классов нет, но на уровне исходников классы, естественно, удобнее.

@mismatch:
mismatch

infoq.com — если вы все еще пишете на ООП языке, но поглядываете в сторону ФП, морщась при упоминании монад и аппликативных функторов, этот доклад для вас.

@Hawat:
Hawat

Как научиться мыслить по ООП-шному? Пытался и в Ruby и в Python понять эту хрень и каждый раз приходил к выводу: "А нахрена оно вообще надо, я все функциями уже накатал". В lua худо-бедно понял концепцию объекта как массива с данными и функциями, но это ведь только одна небольшая часть ООП(которая в контексте lua вообще не ООП). В общем может есть литература на русском по этому вопросу или какие-нибудь бложики?

@mismatch:
mismatch

smashcompany.com — оооччень длинная статья о сильных и слабых сторонах ООП, о том, что SOLID решает проблемы характерные только для ООП. При этом автор выбирает слабые стороны ОО языков программирования и приговаривает как хороши Clojure и Erlang. Статья полна интересных цитат и ссылочек.

@OCTAGRAM:
OCTAGRAM

ru.wikipedia.org
Выложил всё, что мне известно про языки программирования, с которыми был хоть как–то связан SOM. Оказывается если посчитать, их целых 8.

@Strephil:
Strephil

И быдлокод, который я переписываю, это как бы ооп-программа, с кучей типов, унаследованных от одного главного. Но написано на C, и там как сделано, просто куча, куча, куча кода, который дублируется из файла в файл, из файла в файл.
Но это я трогать не буду, оставлю, как есть.

@RA:
RA

Как называется метод который в абстрактном классе определён и содержит код, но который обязательно нужно переопределить в потомке?
Это точно не абстрактный метод, потому что он содержит код. А нужен он для того чтобы в потомках можно было вызвать этот "дефолтный" метод при необходимости.
(ЯП не имеет значения)

@qnikst:
qnikst

Итог предыдущих постов, про семейства типов и классы.

В ООП можно сделать открытый класс с базовой реализацией, тогда потомки типа могут переопределить реализацию метода. Близкий вариант в haskell это
сделать дефолтную реализацию внутри typeclass-а. Т.е. тут паритет (почти, если интерсно, то продолжу об этом случае отдельно).

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

type family FooT a
class Foo a where foo :: a -> FooT a

вопрос, как в хацкиле сделать? (похоже что вменяемыми методами не реально), и как сделать в ООП (прочей парадигме):

Перевод с птичьего языка:

мне хочется иметь метод:

<FooT a> foo(a)

где `FooT a` это функция из типов в типы, и если для указанного типа, решение FooT a неизвестно, то, чтобы подставлялось `a`, а имплементация foo == `id` (отображениие элемента самого в себя).

Принимаются идеи на любом ЯП, но все должно быть решено в compile time. Доп ограничения на простраство типов вводить можно.

@13oz:
13oz

Кстати, жуец. Я все забываю попросить порекомендовать мне годную книгу на тему введения в объектно-ориентированное программирование. Банду четырех не предлагать - она уже в списке на чтение.

@skobkin-ru:
skobkin-ru

LsObject — мой любимый класс:
abstract class LsObject {

}

@13oz:
13oz

Объекты создаются с помощью инстанцирования класса. Инстанцирования, блять!! Убейте переводчика

@Strephil:
Strephil

Лабаю быдлокод на асме, и вдруг мне захотелось всяким там наследований, полиморфизмов и пр.
может быть, перебыдлокодить на ц с крестами?

@Zert:
Zert

А расскажите мне, уважаемые доны, в чём суть «разделения языков» на фэпэ, оопэ, дэпэ и подобные аббревиатуры? Кому-нибудь из вас в жизни реально пригодилось осознание того, что он пишет на так называемом функциональном/обжектно-ориентированном/декларативном и т.п. языке? В чём смысл разделения? Вот я пишу на Erlang, там «клёвые процессы» и сообщения, ну да, он типа считается ФП, но мне от этого факта ни холодно, ни жарко. Захотел писать на Go, там тоже процессы, каналы, но он «не считается» ФП. Как-то тоже параллельно. Писал на ссях, петоне, «хвашкиле», скалке, лишпе, никогда не задумывался, ООП это или ФП, или ещё какая ересь. В чём суть подобной классификации? Зачем «адепты ФП срутся с адептами ООП»? Хуй его знает.

@NokitaKaze:
NokitaKaze

habrahabr.ru 

@ak:
ak

А вы знаете, что травматика в законе об оружии называется "огнестрельное оружие ограниченного поражение" сокр. ОООП. Напоминает, что-то? И тем и тем можно выстрелить себе в ногу =]

@ReadMe:
ReadMe

помню что засыпал размышляя о красном развратном кубе написанном на пхп с использованием ООП...

@OCTAGRAM:
OCTAGRAM

habrahabr.ru
IBM SOM: внешняя объектная система с поддержкой наследования

// Статья стала пропуском на хабрахабр, от кого, не понятно, но и так сойдёт.

@ReadMe:
ReadMe

опять не могу сосредоточится. путаюсь в собственныз классах и методах.

@hohoho:
hohoho

есть ли тут гуру в плюсах? имеется вопрос, был бы благодарен за ответ.
в делфи есть такой механизм, как message методы, позволяющий избавиться от длинных case в оконной функции окна и транслировать сообщение по его номеру в соответствующий метод.
Более подробно (если есть желание) можно почитать тут например delphikingdom.ru

Если вкратце, то это можно обозначить таким кодом:

TSomeClass = class
private
procedure WMMessage(var Message: TMessage); message CONST_NUMBER;
protected
procedure DefaultHandler(var Message); override;
procedure HandlerProc(var Message: TMessage);
end;

{ TSomeClass }

procedure TSomeClass.WMMessage(var Message: TMessage);
begin
{код обработки}
Message.Result := 0;
end;

procedure TSomeClass.HandlerProc(var Message: TMessage);
begin
Dispatch(Message);
end;

procedure TSomeClass.DefaultHandler(var Message);
begin
with TMessage(Message) do
Result := DefWindowProc(Handle, Msg, WParam, LParam)
end;

Вызов Dispatch с сообщением под номером CONST_NUMBER приведет меня в метод WMMessage. Если соответствующего метода нет, то сообщение отправляется в DefaultHandler, где скармливается стандартной оконной процедуре.
Этот приём можно использовать не только для работы с винапи и я его активно использую в SDK плагинов для QIP — на делфях я сваял обертку, позволяющую работать с сдк более удобным способом.

Собственно, вопрос: можно ли похожую схему сделать компактно на сях, не таская за собой кучу зависимостей? Я в курсе только про существование карты сообщений в MFC и WTL. Есть ли что-то еще?
Рецоменд плиз.

@folex:
folex

Жуйк, а не посоветуешь книгу/статью по ООП? Именно по ООП, волнует терминология и все такое.
В принципе, не особо важно, какой там будет язык, но C# предпочтительнее.

@molny:
molny

Правду сказал один человек: "ООП — погремушка академиков и переучившихся студентов."

@NEKT:
NEKT

Идеальная разработка с точки зрения ООП
blogerator.ru

@zhu:
zhu

фанатики ООП сбежались и раскудахтались: оооопэээ, дооооо, кококококо habrahabr.ru доооо! пекарь! пекарь! абстракции! полиморфизм! кокококо.

@asvil:
asvil

ООП говно, всё верно. habrahabr.ru

@SLX:
SLX

Вообще не знаком с ООП( ну так, в кратце ). Что стоит почитать? Пишу преимущественно на python(django).

@kb:
kb

Осознал наконец-то аналогию между переопределением методов при наследовании в ООП и dynamic scoping'ом переменных.

@HeX:
HeX

Подхожу я такой к классу UIVIEW и говорю "Запили мне объект View, который будет основным представлением, быыыыстра блять!". А он мне с вертушки в щи поясняет: "Иди нахуй, долбоеб, уже все сделано до тебя, не еби мозг." И я такой "Лааааадно".
Вот оно ваше ООП под гейОС — компилятор все сделает, не забывай мышкой по экрану возить.

@HeX:
HeX

вот смотри, ты хочешь создать собачку. Все собачки одинаковые, они относятся к классу собачка. И вот, ты создаешь собачку, описываешь ей четыре лапки, хвостик, ушки, мордочку. И ты говоришь "создайте мне новую собачку", ты можешь назвать ее Бобиком. И ты можешь делать с ним что угодно. Можешь сказать "Бобик, иди туда", и он пойдет. Можешь сказать — "Бобик, убейся" и объект исчезнет.
Мне объяснили ООП, окок:3

@abudaster:
abudaster

igor.quatrocode.com на первый взгляд вроде хорошая статья, надо будет ознакомиться на досуге. Выкладываю тут, чтобы не потерять ссылку

@Strephil:
Strephil

lab.madscience.nl

@NokitaKaze:
NokitaKaze

Я разделил синтез данных от отображения и стало значительно легче. И теперь я могу подключить ещё одно отображение к уже синтезированным данным

@Zert:
Zert

За последние пару дней наткнулся на несколько ООП-срачей, сформулировал своё мнение на этот счёт: erlang-russian.org

@akastargazer:
akastargazer

У меня есть некий объект, к которому можно цеплять различные атрибуты. Вот, например, двигатель внутреннего сгорания. У него есть некий признак, например — количество цилиндров. Или там, ход поршня. Это параметры или атрибуты?

Интересно, чем атрибут отличается от параметра?

Как нам сообщают словари, АТРИБУ́Т (лат. at-tributum — "приданое, присовокупленное, предназначенное, наделенное") — признак, качество, свойство, предмет, сопровождающий какое-либо явление.

Ну а ПАРАМЕТР (греч. parametron — отмеривающий) 1) показатель, величина, значение которой остается постоянным в пределах рассматриваемой задачи, зависимости; 2) величина, показатель, характеризующий к.-л. свойство устройства, процесса, вещества; 3) показатель, величина которого оказывает существенное влияние на экономические процессы.

Наверное, в контексте ДВС мы имеем дело с атрибутами.

@13oz:
13oz

жуец, я правильно понял, что при создании класса нельзя одновременно иметь и __slots__ и __dict__?

@borman:
borman

Алсо, я в печали. Хотел слегка пропатчить исходники, а там такое наверчено, что я боюсь соваться без фонарика. Велкам ту зе риаллайф, блеать.