тип против интерфейса: зачем тогда печатать?

Расширяя свой кругозор с помощью javascript вместе с моим опытом работы с python, я задумался.

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

В языках со статической типизацией тип имеет очень сильное центральное значение. Тип и интерфейс строго связаны. Например, в java, когда вы объявляете интерфейс FooIface и объект, реализующий этот интерфейс, вы не можете использовать его в контексте, требующем BarIface, даже если они совершенно одинаковы с точки зрения методов, сигнатур и исключений.

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

Эта точка зрения доведена до крайности в javascript, где каждый объект в любой цепочке прототипов является просто объектом. вы спрашиваете тип каждого объекта в javascript, и он скажет вам, что это объект.

Мне кажется, что понятие типа для этих языков находится на грани бесполезности. Что же тогда действительно жизненно необходимо? Имеет ли тип реальное значение в языках с динамической типизацией?


person Stefano Borini    schedule 08.01.2010    source источник


Ответы (3)


Я не вижу бесполезности. Рассмотреть возможность:

1). Когда вы строите объект

var myThing = new Thing( ... );

Тип Вещи имеет значение.

2). Метод вещи может использовать

this.aProperty

в соответствии со своим знанием типа

3). Вы можете использовать instanceof для определения типа

person djna    schedule 08.01.2010
comment
это интересные моменты. Дайте мне подумать об этом, и я вернусь позже в конце концов. +1 кстати. - person Stefano Borini; 08.01.2010

Я склонен понимать слово «тип» как эквивалент слова «класс» в Python. Это верно только на 99%, но достаточно близко.

>>> type(object)
<type 'type'>
>>> class X(object):
...  pass
... 
>>> type(X)
<type 'type'>
>>> type(_)
<type 'type'>
>>> type(X())
<class '__main__.X'>
>>> type(X) is type(type)
True

Однако я обычно избегаю слова «тип» в этом случае. В общем, я вижу это следующим образом: слово «тип» подразумевает, что рассматриваемая вещь не является первоклассным объектом.

person balpha    schedule 08.01.2010
comment
Это то, что я имею в виду. Две крайности: в Python типом экземпляра является сам экземпляр. В C++ типом экземпляра является некоторое существо более высокого уровня, недоступное программно [я знаю, что есть способы; это больше с точки зрения философии]. - person balpha; 08.01.2010

Если язык рассматривает только реализованные методы класса, чтобы сделать вывод, каким интерфейсам он соответствует, вы можете случайно реализовать интерфейс. Допустим, в Java у вас есть интерфейсы IA и IB, которые оба определяют метод long getRemainingTime. В этом случае в контракте этих интерфейсов будет указано, в каком формате они будут возвращать (один может возвращать время в секундах, а другой — в миллисекундах). Кроме того, контекст, в котором используются эти интерфейсы, может быть очень разным. Допустим, они называются не IA и IB, а IProgress и IStopWatch. В таком случае возвращаемое время имело бы совсем другое значение. Если бы вы могли поменять местами эти два интерфейса по своему усмотрению, вы могли бы получить действительно неожиданные результаты.

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

person Stefan Schmidt    schedule 08.01.2010