сlass A:
def __init__(self):
self.data = "string"
def cout(self):
print "<< %s >>"%self.data
class B:
def __init__(self):
self.data = 15
def cout(self):
A.__dict__["cout"](self) # monkey
ducks = [A(), B()]
for d in ducks:
d.cout()
абстрактный тип данных
и так, что означает абстрактный тип данных на программирование ?
Для начала надо понимать что такое конкретные типы, конкретные классы. Это классы, объекты которых делают всё сами. Абстрактные же применяются только как предки конкретных и сами ничего не делают.
Зачем они нужны? Грубо говоря, это костыль, который позволяет программисту вызвать метод какого-либо объекта, не зная тип этого объекта. То есть абстрактный класс может быть интерфейсом к функциям каких-то конкретных классов, о реализации которых программист может даже не знать.
Почему я сказал костыль? Потому что идеология абстрактных классов принуждает программиста делать работу, которую мог делать компьютер.
Например, для замены абстрактных классов можно было бы применить другие сущности. Назовем их Утки и Обезьянки.
Утка - это вывороченный наизнанку абстрактный класс, который автоматически генерируется на основе любых конкретных классов, у которых есть открытые функции с одинаковым объявлением.
То есть Утку можно использовать как-то так (на квази-C++):
duck<Class1, Class2> &duckArr[] = {class1, class2, ... };
foreach( d in duckArr) d.my_method();
Обезьянка - это выражение которое бы позволяло одному конкретному классу "воровать" функцию у другого, подменяя неявный указатель this на указатель другого типа. Хотя тут не совсем ясно что тут было бы лучше: чтобы при этом метод тянул все связанные данные и функции, или чтоб их включение зависело от программиста. Вероятно, лучше чтобы был выбор.
Про "обезьянок", вероятно, совсем бред. Даже Питон некоторое время сопротивлялся такому безобразию. Но всё же в версии 2.6 такого можно добиться:
Код:
то есть, метод был удачно "похищен" без всякого наследования. Но на практике такое наверное не пригодится. Для C++ такое возможно только для статических методов. Но от этого радости нет.
void func(typeA a);
можно было бы придумать синтаксис типа:
func(<typeB> b);
которая генерировала бы функцию с новым типом без всяких шаблонов. Правда, тут будет проблема с типом возвращаемого значения. Ну и с классами труднее такую фишку сделать.
Цитата: Kogrom
Или ещё безумная идея, насчет шаблонов, которые так же можно посчитать абстрактным типом.
Такие штуки называются генериками в одном малоиспользуемом фреймворке.
А в предельном случае вообще макросами (см. подпись).