LINUX.ORG.RU

[тип][ооп][интерфейс]Почему считается, что тип == интерфейс?

 ,


0

1

Цитата из TAPL (глава 18.1):

Подтипы. Тип объекта — его интерфейс (interface), — это просто множество имен и типов его операций. Внутреннее представление объекта не фигурирует в его типе, поскольку оно не влияет на набор действий, которые могут быть проделаны над объектом.

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

★★★★★

Не возможна

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

> такая ситуация — это фейл

но как компилятор может об этом узнать? и даже исходя из цитаты с TAPL, равноценность семантики не утверждена

korvin_ ★★★★★
() автор топика

УжОс. Погуглил про TAPL. Это какой-то фундаментальный труд, посвященный программистким абстракциям, возведенным в квадрат.

Нашел перевод. Читается с трудом, с огромным трудом. Неужели в этой книге содержиться ценная информация а не обычный словоблуд, фапанье на математику и жонглирование абстракциями.

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

Типичный баттхерт неосилятора.

Угу. Но ничего, вот появится какое-нибудь «трансцендентное программирование», выходящее на очередной новый уровень абстракций, вот тогда анонимус будет срать кирпичами.

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

Смотря что конкретно. По крайней мере налицо разрыв с индустрией. Пинать за разрыв только индустрию - глупо. Бизнес готов принять все, что способно усовершенствовать процесс разработки и тем самым получить конкурентное преимущество. Ан нет.

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

> Ну ты б начало главы 18.1 прочитал

может ты выделишь нужные фразы?

если ты про

Большинство споров на тему <<В чем сущность такого-то явления?>> скорее проявляют предрассудки их участников, чем проясняют какую-либо объективную истину, касающуюся темы спора. Попытки точного определения термина <<объектно-ориентированный>> в этом смысле не являются исключением. Тем не менее, можно отметить несколько основных конструкций, которые имеются в большинстве объектно-ориентированных языков, и которые все вместе служат основой для характерного стиля программирования с хорошо известными достоинствами и недостатками.

то 1) в конце там указывается, что выделены важные, основные концепции; 2) ничего не сказано, почему принято, что тип == интерфейс

korvin_ ★★★★★
() автор топика

Мне кажется, что сложность материала, представленного в книге в состоянии породить одну мерзкую проблему. Возможно сильное искажение информации при передачи от одного человека другому. Где гарантии, что ТС понял сказанное именно так, как думал автор книги. Возьмем хотя бы термины. Где уверенность, что ТС и автор понимают под словами «тип»,«объект»,«интерфейс» одно и тоже. Может автор книги вкладывал в эти слова совсем другой смысл, чем тот, на который опирался ТС при попытке понять эту фразу. Получается, что в понятиях автора текст логичен, а с использованием понятий ТС текст превращается в белиберду.

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

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

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

нет, не превращается. текст (для меня) в основном понятен

То есть ты уверен, что термин «интерфейс» ты понимаешь именно так, как надо?

pathfinder ★★★★
()

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

В том и смысл интерфейса (= typeclass в другой системе) - чтобы у разных объектов мог быть одинаковый интерфейс, но разная реализация.

Там чуть раньше:

Вероятно, самая фундаментальная характеристика объектно-ориентированного стиля — это то, что когда по отношению к объекту применяет- ся некоторая операция, объект сам определяет, какой код ее осуществляет. Два объекта с одним и тем же множеством операций (т. е., с одинаковым _интерфейсом_) могут иметь совершенно разные внутренние представления, если каждый из них содержит реализацию операций, работающих с его конкретным представлением. Эти реализации называются _методами_ объекта. Применение операции к объекту (_вызов метода_, method invocation) или, более красочно, _посылка объекту сообщения_, sending a message) приводит к поиску имени метода в таблице методов, связанной с объектом. Процесс поиска производится во время исполнения и называется _динамической диспетчеризацией методов_.

В противоположность этому, обыкновенный _абстрактный тип данных_ (АТД) (abstract data type, ADT) состоит из набора значений, связанных с _единственной_ реализацией операций над этими значениями.

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

> Мне кажется, что сложность материала

А где в тапле сложный материал? Это даже не простенькая «Categories for working matematician». Читается, как худ. лит-ра.

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

Короче интерфейс - тип, разные методы (разные реализации) - это различия между объектами. Ну как у объекта некое поле int name; может быть 2, а может 5. Так и тут - метод name с конкретной сигнатурой может быть один, а может - другой.

anonymous
()

(struct type-name (method-x method-y method-z)) Вот это интерфейс, который указывает, что type-name имеет методы method-x method-y method-z. А какими именно лямбдами мы инициализируем эту структуру (какая будет реализация) - зависит от конкретного инстанса структуры.

anonymous
()

> Ведь возможна ситуация...

Не должно так быть. В C# есть понятие interface. Ну и ес-но, что классы, которые реализуют один и тот же интерфейс должны быть схожи в итоговом поведении. Например, метод Clone() - понятно, что по нему объект должен клонироваться. Понятно, что детали реализации могут различаться, в силу архитектурных особенностей классов, но итоговое, результирующее поведение должно быть схожим.

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

> В том и смысл интерфейса (= typeclass в другой системе) - чтобы у разных объектов мог быть одинаковый интерфейс, но разная реализация.

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

korvin_ ★★★★★
() автор топика
Ответ на: комментарий от pathfinder

> То есть ты уверен, что термин «интерфейс» ты понимаешь именно так, как надо?

огласите весь список пониманий, пожалуйста

korvin_ ★★★★★
() автор топика
Ответ на: комментарий от hibou

> Не должно так быть. В C# есть понятие interface. Ну и ес-но, что классы, которые реализуют один и тот же интерфейс должны быть схожи в итоговом поведении. Например, метод Clone() - понятно, что по нему объект должен клонироваться. Понятно, что детали реализации могут различаться, в силу архитектурных особенностей классов, но итоговое, результирующее поведение должно быть схожим.

это может быть понятно разработчику, но не компилятору

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

> разная реализация одной семантики — это одно, а разная реализация разной семантики — это другое.

Тип - это названия методов, которые определены и их сигнатура (то есть интерфейс). Какие методы ты туда всунешь - это вообще не важно и семантика их не важна. Если поменять одну реализацию метода на другую - ты получишь просто другой объект того же самого типа.

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

> (struct type-name (method-x method-y method-z)) Вот это интерфейс, который указывает, что type-name имеет методы method-x method-y method-z. А какими именно лямбдами мы инициализируем эту структуру (какая будет реализация) - зависит от конкретного инстанса структуры.

еще раз: отличие реализации при сохранении семантики — это понятно, но как быть с различием семантики? да, когда в языках интерфейсы сильно абстрактны (типа как в Go, например), то все понятно, но как тогда можно тип отождествлять с интерфейсом?

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

> Тип - это названия методов, которые определены и их сигнатура (то есть интерфейс). Какие методы ты туда всунешь - это вообще не важно и семантика их не важна. Если поменять одну реализацию метода на другую - ты получишь просто другой объект того же самого типа.

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

korvin_ ★★★★★
() автор топика
Ответ на: комментарий от hibou

> Думаю, если ты запилишь в методе Clone() что-то вроде Форматирования диска, то это будет ССЗБ. :)

понятно, что ССЗБ, но код-реюз же нужен, а изучать досконально реализацию «чужого» класса, чтобы убедиться, что там нет удаления разметки диска противоречит инкапсуляции и собственно ООП =/

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

Мне не совсем понятно, что тебе тут смущает. То, что объекты одного типа могут вести себя по-разному (иметь разную семантику методов)? Да, могут. Смысл типа - определять набор операций, которые мы можем производить над объектом. Это все что нужно с формальной точки зрения, прояснить которую и есть цель тапла, «общность семантики» - это критерий субъективный, его научно исследовать нельзя. То есть сигнатуру методов - интерфейс. Семантику тип не определяет и не должен. Вот если мы такие типа дополнительно разделим каждый на совокупность подтипов так, чтобы в любой подтип попадали только объекты с общей семантикой - получим классы.

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

> но это бред, все равно, что поменять, например, собаку на холодильник, один фиг реализует интерфейс «издавать звуки», но это объекты совершенно разных типов, с совершенно разным поведением

Раз и собака и холодильник издают звуки, то вполне логично, что тип собаки и тип холодильника - подтипы типа «издающих звуки». С другой стороны - соака есть подтип типа «кусающихся», а холодильник - подтип типа «морозящих». То есть разницу семантики при желании ты можешь фиксировать уточняя интерфейсы. Выделяя некоторое дополнительное к интерфейсу поведение (которым они будут отличаться) в новые интерфейсы, которые уже различны.

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

Ну кстати, если классы обоих объектов поддерживают интерфейс издавать звуки и только этот интерфейс требуется внешней сущности для работы с объектами этих классов, то действительно разницы никакой. Разве что внешняя сущность может спревередничать и сказать, что это не тот звук. :)

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

В конце концев, если у тебя есть интерфейсы, и ты хочешь каждую реализацию интерфейса выделить в отдельный тип, то тебе достаточно просто к каждой такой реализации добавить «фиктивный» интерфейс (для каждой реализации различный). Этот интерфейс никакого поведения не определяет - просто нужен для различения.

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

> Этот интерфейс никакого поведения не определяет - просто нужен для различения.

Например, этот интерфейс может возвращать имя класса, которое определяет. Тогда еще добавим интерфейс «быть классом» в котором будет метод GetClass(), реализация которого в каждом классе будет дергать метод соответствующего интерфейса. Рефлексия искаробки!

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

> понятно, что ССЗБ, но код-реюз же нужен, а изучать досконально реализацию «чужого» класса, чтобы убедиться, что там нет удаления разметки диска противоречит инкапсуляции и собственно ООП =/

Enjoy your duck typing

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

разная реализация одной семантики

Семантика тут может состоять только в том, что, например, если мы хотим сделать интерфейс открытия / закрытия устройств, то у нас будут методы open :: Path -> IO Device и close :: Device -> IO () и производные, например with d f = bracket (open d) (close) f (это в идиомах хаскеля). А реализация может быть абсолютно произвольной. Вот в TAPL и говорится, что класс это набор сигнатур методов, что реализует его интерфейс.

но компилятору это как-то до лампочки

А компилятор и не должен препятствовать реализовать эти методы (как open и close для разных устройств) абсолютно произвольным способом.

quasimoto ★★★★
()

> Почему считается, что тип объекта — его интерфейс?

Что значит «считается»? Кем «считается»?

Все зависит от того как (т.е. через что) определен тип и как определен интерфейс.

«Классическое» определение типа (для императивных языков) - множество допустимых значений + множество допустимых операций над ними.

«Классическое» определение интерфейса для императивных языков опять же - контракт на выполнение множества операций.

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

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


Я больше скажу, если два класса реализуют один и тот же интерфейс одним и тем же образом - это бессмысленный копипаст, а идентичную реализацию надо выносить в общего предка.

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

> но компилятору это как-то до лампочки

При чем тут компилятор? Программы, вообще-то, пишутся не для компиляторов. И даже не для вычислителей. Программы пишутся для людей.

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

> «Классическое» определение типа (для императивных языков) - множество допустимых значений + множество допустимых операций над ними.

Я бы сказал, что классическое определение состоит в следующем: 1. T - решетка (T - совокупность всех типов) 2. существует отображение: f: T * V -> Boolean (V - совокупность всех значений) 3. x, y in T; z in V; x <= y, f(x, z) = True => f(y, z) = True

это для монотипов с подтипированием.

anonymous
()

Ответ заключается в вопросе. Определение типа:

Тип объекта — его интерфейс (interface), — это просто множество имен и типов его операций.

Объяснение, почему оно такое, а не иное:

Внутреннее представление объекта не фигурирует в его типе, поскольку оно не влияет на набор действий, которые могут быть проделаны над объектом.

anonymous
()

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

Это уже проблемы программиста, а не определения.

Тип — это совокупность методов, за которые можно подергать объект. Т.е. интерфейс. Именно поэтому самое правильное, с точки зрения теории, ООП — в хаскеле. А все эти class blabla {...} императивных языков — от убогости выразительных средств.

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

> но это бред, все равно, что поменять, например, собаку на холодильник, один фиг реализует интерфейс «издавать звуки», но это объекты совершенно разных типов, с совершенно разным поведением

Если твоей программе нужно поиздавать звуки из собаки и холодильника, то тебе придётся это как-то реализовывать и всё равно вводить абстракцию «издаватель звуков». А уж насколько язык позволяет описать такой тип — зависит от языка. В C++, например, с этим крайне херово. В динамический языках — проще, так как там можно для себя определить «тип» (в обход дерева классов) как совокупность методов и дергать их по имени. Поэтому нормального ООП с С++-подобных языках просто нет.

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

огласите весь список пониманий, пожалуйста

Я думаю, ты сам понимаешь, что это нереально. Я же не говорил, что есть некий ограниченный набор строго обособленных друг от друга понятий. И в силу их строгой обособленности можно легко описать их в виде некоторого «списка пониманий». Понимания сильно размыты. Это мешает проводить границу - где заканчивается одно понятие и начинается другое.

Если говорить об «интерфейсе», то можно оперировать этим словом лишь в рамках языка (типа C#), где понятие с таким названием заложено в сам язык. Можно говорить об «интерфейсе», просто как о наличии некоторого взаимодействия, согласованного с некоторым стандартом(договором, идеей, концепцией). Можно поговорить об «интерфейсе», как о наличии некоторой совокупности методов, обладающих некими свойствами и общей идеологией. Ну и все возможные плавные переходы от одного к другому.

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

> В хаскеле нет ООП. классы и интерфейсы никак не связаны с ООП.

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

Такая вот ирония судьбы.

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

> Вот только как раз в хаскеле реально работает механизм абстракций и типов данных, который должен был, по мнению идеологов ООП, и быть сутью ООП.

Суть ООП - message passing. Бред об абстракциях и типах данных к ООП не имеет отношения.

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

> ООП вырождается в набор костылей

система тайпклассов в результате вырождается в не меньший набор костылей

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

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

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

> Суть ООП - message passing.

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

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

> Если ехать, то нужен хороший механизм составления абстракций, потому что любая программа — это система абстракций разного уровня.

Но при чем тут ООП?

приводит в замешательство ООП-программиста.

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

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

Если ехать, то нужен хороший механизм составления абстракций, потому что любая программа — это система абстракций разного уровня.

Но при чем тут ООП?

Притом, что ООП - это хороший способ выстроить и упорядочить систему абстракций.

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

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

> Но при чем тут ООП?

Получается, что ни при чем. Значит, ООП — это только шашечки.

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

Откровения от анонимуса? Вы мне предлагаете написать helloworld, демонстрирующий данный аспект языка? Ну так мне лень. Сами пишите.

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

Это тащемта проблемы программиста, а не языка.

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