LINUX.ORG.RU

Зачем нужно ООП

 


2

3

Далёк я буду от правды если скажу, что единственная причина появления ООП - нельзя было сказать draw(circle) и draw(rectange) в одной программе (где rectange и circle - переменные с различными структурами)?

★★★★★
Ответ на: легко. от anonymous

Полиморфизм и инкапсуляция не изобретение ООП. Интерфейсы не изобретение ООП, указатели на функции и структуры не изобретение ООП. Наследование ты так и не показал. На си можно писать в ООП стиле, я не с этим спорю.

anonymous
()
Ответ на: комментарий от anonymous

Какие там объекты в рантайме, если тут просто набор указателей на функцию?

Какие там классы в компилтайме? Где ты их видишь?

Где методы и сообщения?

Напомню код:

typedef struct shape_info {
...
    void (*draw)(void *);
...
} shape_info_t;

Использование:

void
foo(shape_info_t *si, void *sh1, void *sh2)
{
    ...
    si->draw(sh1);
    ...
    si->draw(sh2);
}

Кстати, там вполне мог быть указатель на функция intersection(void *, void *), который бы отвечал за пересечение. Может так вам легче будет понять, что какой-то функции тут не подчиняются объектам.

anonymous
()

В С есть возможность создавать новые типы. ООП дает возможность определять операции для этих типов. Это делает код, работающий, например, с векторами, гораздо прозрачнее.

hotpil ★★★★
()
Ответ на: комментарий от anonymous

при том, что vala генерирует код на C для библиотеки GLib. которая, сюрприз — реализует объектную модель GObject на С (а поскольку C API с точки зрения ABI прозрачен, биндинги к этой объектной модели элементарно пишутся для любого языка, где есть FFI).

если бы ты посмотрел на сгенерированный код, ты увидел бы как конкретно выглядит реализация этой модели GObject на plain C.

и что конкретно нужно сделать, чтобы реализовать: вызов методов, динамическую типизацию, диспетчеризацию методов и виртуальные методы, свойства, а также, сюрприз — инкапсуляцию (static функции), наследование (конструктор construct и реализация типизации и диспетчеризации), полиморфизм наследования (проверка корректности типов при присваивании, реализация диспетчеризации и динамической типизации).

и ничего особенного тут нет — в OS/2 была SOM, тоже похожим образом реализована, только гибче.

в этих объектных моделях реализованы метаклассы, свойства и динамическая типизация, например.

то есть: они гибче, чем объектная модель в С++ (реализованная через VMT + virtual), и при этом реализованы на «не объектном» языке plain C.

При чем тут Vala или даже Си? В приведенном примере кода нет ООП, есть набор указателей на функции.

знакомься, это методы. а дополненные корректной семантикой диспетчеризации и типизации --

это и есть, сюрприз, ООП. ООП не зависит от языка,а зависит от ОО концепций + некоторой ОО модели, реализующей эти концепции.

сам набор концепций не важен: 3 принципа — наследование, инкапсуляция, полиморфизм в ОО модели Simula/C++/C#/Java/...; 2 принципа — посылка сообщений и инкапсуляция в SmallTalk, ObjC; 4 принципа — родовые функции, мультиметоды метаобъектный протокол и динамический полиморфизм в CLOS; 2 принципа — динамический полиморфизм сотрудничества и композиции (или, мультиметоды и делегаты) в COS (см. cos-draft-oopsla09.pdf); ... что там в Eiffel, который тоже кодогенерирует через C.

это всё разные способы реализации ООП.

anonymous
()
Ответ на: комментарий от anonymous

Какие там объекты в рантайме, если тут просто набор указателей на функцию?

внезапно, пойми во что компилируется VMT + virtual метод. вот в это самое. вся разница как и когда заполняется VMT — в компайлтайме или в конструкторе.

Какие там классы в компилтайме? Где ты их видишь?

класс — это ADT тип + реализация полиморфизма и диспетчеризации (для наследования)

void foo(shape_info_t *si, void *sh1, void *sh2)

первый параметр — это this в С++ (адрес self в ObjC, Current в Eiffel). сам объект.

si.foo(sh1, sh2) <=> foo(si,sh1,sh2) — это одно и то же, с точностью до синтаксического сахара.

anonymous
()
Ответ на: комментарий от anonymous

Наследование ты так и не показал

в модулях ядра: версионирование модулей для этого.

в GObject: см. код, скодогенерированый valac из vala в С, там не всё тривиально.

anonymous
()
Ответ на: комментарий от hotpil

при этом в системе типов получается дырка. если передать указатель на другой тип в «метод» — должна выполняться проверка на полиморфизм.

алсо, наследование для такого «нового типа» в простом случае — костылить вручную (или см. как в GObject реализовано).

алсо, что нужно, чтобы реализовать метод toString для всех типов, включая новый? опять костыли? в COS на это говорят «динамическая композиция (полиморфизм), динамическая диспетчеризация (мультиметоды) и расширяемость (делегаты, включая на обычные, не объектные типы)». но в общем случае такое — нетривиально.

в модулях ядра обходятся дисциплиной и соглашениями, в GObject — реализацией объектной модели в рантайме.

anonymous
()
Ответ на: комментарий от Freyr69

Мне не нужна ссылка на википедию, мне нужно твое понимание ооп.

Просто удобный способ писать программы. Если алгоритмы обработки данных не универсальны и не глобальны, их гораздо удобнее локализовать в одном объекте вместе с обрабатываемыми данными. В результате программа получается более компактной и простой для понимания. На самом деле и в процедурном программировании поступают так же - выносят специфичные для конкретного типа функции обработки данных в отдельную библиотеку, которая, зачастую, имеет сходное название с тем типом, который обсчитывает. И, ЧСХ, объём вычислений и быстродействие алгоритмов при этом не меняется. Меняется лишь читабельность программы.

anonymous
()
Ответ на: комментарий от anonymous

Нет, сами объекты передаются вторым и третьим параметром.

anonymous
()
Ответ на: комментарий от anonymous

при том, что vala генерирует код на C для библиотеки GLib. которая, сюрприз — реализует объектную модель GObject на С (а поскольку C API с точки зрения ABI прозрачен, биндинги к этой объектной модели элементарно пишутся для любого языка, где есть FFI).

Пусть генерирует. Как это связано с приведённым кодом? GObject - убогая реализация убогой модели ООП. Зачем она вообще нужна? На си голом писать с её помощью - ад. Vala могла быть самостоятельным языком. Биндинги для других языков? Зачем?

В любом случае, к приведенному коду это все не имеет отношения.

anonymous
()
Ответ на: комментарий от anonymous

знакомься, это методы.

Нет, это просто указатели на функции, они не привязаны к объекту.

anonymous
()
Ответ на: комментарий от anonymous

Внезапно, пойми во что компилируется VMT + virtual метод. вот в это самое. вся разница как и когда заполняется VMT — в компайлтайме или в конструкторе.

Да какая разница во что это все компилируется? Пусть компилируется в структурам с указателями, но при чем тут тот код с набором указателей на функции? Так писали до эры ООП, примерно в это же компилируются и тайпклассы хаскеля(которые не ООП) и что теперь? Да любой динамический полиморфизм будет к этому сводиться в итоге. Но не станешь же ты утверждать, что полиморфизм придумали в ООП?

anonymous
()
Ответ на: комментарий от anonymous

void foo(shape_info_t *si, void *sh1, void *sh2)

первый параметр — это this в С++ (адрес self в ObjC, Current в Eiffel). сам объект.

Мне кажется, что ты не так понял этот пример. Сами фигуры передаются параметрами sh1 и sh2, а вот набор функций - первым. Это не аналог this. И тут действительно набор функций не привязан ни к какому объекту.

Вот код на haskell

class Shape a where 
  draw :: a -> ()

foo :: (Shape a) => a -> a -> ()

Как мы можем делать что-то похожее на Си? Да примерно так же, как делалось в том самом примере=) А ты там видишь ООП, а не тайпклассы Haskell.

Если что-то реализовано через указатели на функции, то это еще не повод записывать сами указатели на функции в ту или иную концепцию. В ООП нет указателей на функции. В ООП есть объекты, посылка сообщений и т.п.

forCe
()
Последнее исправление: forCe (всего исправлений: 1)
Ответ на: комментарий от anonymous

Да любой динамический полиморфизм будет к этому сводиться в итоге. Но не станешь же ты утверждать, что полиморфизм придумали в ООП?

нет, я буду утверждать что в ООП придумали свой, особенный, объектно-ориентированный полиморфизм. в отличие от какого попало. этот «ООП полиморфизм» нужен для поддержки полиморфного присваивания

Base b = Child c; b.foo() //c.foo(), а не b.foo() ибо динамический тип другой, и foo -- виртуальный метод.

а также для поддержки наследования (то есть, то самое b.foo() — поиск и диспетчеризация в нужную реализацию, в нужном предке)

например: syscall.c — здесь смотрим

asmlinkage int (*original_call) (const char *, int, int);
/ * ... */

asmlinkage int our_sys_open(const char *filename, int flags, int mode)
{
	/* ... */

	/* 
	 * Call the original sys_open - otherwise, we lose
	 * the ability to open files 
	 */
	return original_call(filename, flags, mode);
}

вот это вот original_call — это реализация наследования (ср. (call-next-method)) — костылями и верёвками, из подручных средств. заполнение этого original_call — см. в init_module(), в рантайме.

то есть: это «объектно-ориентированный» рантайм для поддержки механизмов реализации ООП, в модуле ядра.

то есть, ещё раз: есть концепция ООП, цель (увеличение code reuse и модульности) и есть концепция ООП, механизмы (наследование, инкапсуляция, полиморфизм; single dispatch и VMT; или другой набор механизмов — вставь любые 3,2,4).

и есть воплощение, или реализация этой модели ООП в рантайме, реализация ООП в рантайме — конструкторы, заполнение тайпинфо или obj id или других метаданных для диспетчеризации, реализация диспетчеризации.

Пусть компилируется в структурам с указателями, но при чем тут тот код с набором указателей на функции?

при том, что это — воплощение в ООП-рантайме ООП-концепции посредством ООП-механизмов. потому что никаких объектов в том, во что оно скомпилируется, на самом деле нет, методов тоже. методы это синтаксический сахар для функций, а указатели на — синтаксический сахар для this/self/current.

а уже оптимизатор компилятора ООП, если он сильно умный может метаданные для диспетчеризации, в компайл-тайме посчитать, если а) компилятор не дурак б) выполняются некоторые ограничения, чтобы посчитать в CTFE, а не в crt0 RTTI.

anonymous
()
3 июля 2015 г.
Ответ на: комментарий от EnterpriseMobility

А тебя, дурачка деревенского, кто-то вообще спрашивает? Вот уж чье мнение куска говна не стоит, так это твое.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.