Mam abstrakcyjną klasę podstawową (Base
), która ma zdefiniowane pewne cechy układania (StackingTrait
).Scala: Ciekawostka Mixin z abstrakcyjną podstawową klasą
trait Base {
def foo
}
trait StackingTrait extends Base {
abstract override def foo { super.foo }
}
Byłoby to bardzo wygodne, aby zaimplementować podklasa używając następującej składni, ale to nie działa, ponieważ kompilator mówi, że foo musi być zadeklarowana z override
a następnie abstract override
o ponownej kompilacji, które jest nieważne, ponieważ Impl
to klasa.
class Impl extends Base with StackingTrait {
def foo {}
}
Nie mogę myśleć o dobry powód, dlaczego tak składnia będzie niedozwolonych; foo jest logicznie zdefiniowane za pomocą Impl
, więc zamawianie układania w konceptualnie pozostaje takie samo.
Uwaga: Uwaga: Wymyśliłem to obejście, które skutecznie zrobi to samo, co chcę, ale konieczność klasy pomocniczej sprawia, że chcę lepszego rozwiązania.
class ImplHelper extends Base {
def foo {}
}
class Impl extends ImplHelper with StackingTrait
Dlaczego żądana składnia nie jest skompilowana i czy istnieje eleganckie rozwiązanie?
Świetna odpowiedź! Właśnie miałem zadać pytanie na temat tego właśnie scenariusza. Dzięki! –
Właśnie napotkałem ten problem. Linearyzacja jest w tym przypadku słuszna, ale zdałem sobie sprawę z tego, że rzeczywisty cel układania cech jest następujący: Możesz wprowadzić modyfikację z cechą stosu tylko do istniejącej konkretnej implementacji wspólnej abstrakcyjnej klasy/cechy. To znaczy. mają 'listę klasy abstrakcyjnej' i' cechę Mod rozszerza listę'. Nie możesz po prostu napisać 'class Foo extends List with Mod'. Najpierw musisz mieć konkretną listę, np. 'Klasa LinkedList rozszerza List', możesz napisać' class Bar extends LinkedList with Mod'. Mam nadzieję, że ma to sens. –
Zapomniałem dodać, że dotyczy to tylko cech z metodami "abstrakcyjnego pomijania", aby było jasne. Bez takich metod wydaje się, że cechy można dowolnie mieszać. –