Примеси (mix in): организация доступа к полям класса, self
G_Z 08.02.2016 17:33
Начну с задачи, где планировал использовать примеси как вариант множественного наследования.
@main[]
$c[^c::create[]]
^c.action[]
[$c.a]
^c.method[]
[$c.a]
@CLASS
a
@create[]
@CLASS
b
@BASE
a
@method[]
$self.a(3)
@CLASS
c
@create[]
$self.a(1)
$b[^b::create[]]
$bm[^reflection:methods[$b.CLASS_NAME]]
$sm[^reflection:methods[$self.CLASS_NAME]]
^bm.sub[$sm]
^bm.foreach[name;]{
$self.$name[^reflection:method[$b;$name]]
}
@action[]
$self.a(2)
В большинстве случаев объекты класса «c» используются в чистом виде.
Но иногда необходимо расширить их методами объектов класса «b», отнаследованных от класса «a».
Этакий partial, но с наследованием.
При этом хочется, чтобы на код не накладывалось дополнительных ограничений — можно было в любом из пары объектов звать методы любого из них, читать и записывать общие поля.Помочь с методами могут примеси,
пример которых показывал Sumo.
Там они достаточно навороченные, со своими конструкторами, рассмотрим более простой вариант: кладём в поля акцептора ссылки на методы донора.
В результате акцептор имеет полный набор методов.
Остаются две проблемы:
1. методы донора не могут вызывать методы акцептора, так как ничего о них не знают. Решить это можно передачей донора акцептору и использование ссылки в вызовах, как это сделано у Олега с «this», или обратным подмешиванием методов акцептора донору;
2. подмешанные акцептору методы не могут обращаться к его полям, так как их self — указатель на объект-донор, а не на акцептор.
Обе проблемы, конечно, решаемые, но приводят к тому, что код донора должен знать, что может быть подмешан, что приводит к необходимости всё писать с оглядкой на такую возможность, к примеру, везде использовать «self.this», вместо «self».
Огульно пришла в голову мысль о полезной возможности подмены объекта, на которую указывают переменных «self» методов, но Олег правильно заметил, что будут проблемы с поиском и обращением к унаследованным методам и полям донора.
Быть может есть элегантный подход, которого я не вижу?
- Примеси (mix in): организация доступа к полям класса, self, G_Z [M] 08.02.2016 17:33