Интерфейсы / Миксины
Пожалуйста поищите еще языки в которых есть миксины
Классы в Vala могут реализовывать любое количество интерфейсов. Каждый интерфейс - это тип, очень похожий на класс, но у которого не может быть экземпляров. Реализуя определенный интерфейс, экземпляры данного класса становятся экземплярами и интерфейса, и их можно использовать везде, где требуется объект определенного интерфейса.
Процедура реализации интерфейса такая же, как и при наследовании от абстрактного класса - если нужно иметь возможность создавать экземпляры этого класса, то придется реализовать все объявленные в интерфейсе методы.
Вот пример простого определения интерфейса:
В этом коде описан интерфейс ITest
, который наследует от GLib.Object
и содержит два поля. data_1
- свойство, такие вы уже видели, но он абстрактный. Vala не будет реализовывать это свойство, но у классов реализующий данный интерфейс будет требовать его присутствия, с get и set внутри, т.к. интерфейсы не могут иметь поля данных. Второе поле - это метод method_1
. Данный метод должен реализовывать классами, реализующими данный интерфейс.
Простейший способ реализации этого интерфейса:
И может быть использовано следующим образом:
Интерфейсы Vala не могут наследовать от других интерфейсов, но могут требовать их присутствия, что при работе с ними означает одно и то же. Например можно сказать, что любой класс, реализующий интерфейс List должен реализовывать так же интерфейс Сollection. Синтаксис в подобном случае не отличается от синтаксиса, описывающего реализацию интерфейса классом:
Определение List принуждает при его реализации реализовывать и класс Collection, таким образом Vala вынуждает при реализации интерфейса расписывать все интерфейсы, от которых он зависит:
Vala интерфейсы могут требовать и классы. Если в требованиях указано название класса, то интерфейс может быть реализован только в тех классах, которые наследуют от этого указанного класса. Обычно это применяется, чтобы быть уверенным, что экземпляр интерфейса так же наследует от GLib.Object
, таким образом интерфейс может использоваться в качестве типа для свойства.
Фактически интерфейсы не могут наследоваться от других интерфейсов, но это формально - на самом деле в Vala это работает, как и в других языках, но с дополнительной особенностью предпосылки классов.
Есть еще одно важное отличие Vala интерфейсов от таковых в Java/С#: Vala интерфейсы могут иметь не абстрактные методы! Vala позволяет в интерфейсе реализовывать методы, поэтому интерфейсы Vala можно использовать как миксины. И это ограниченная форма множественного наследования.
Mixins and Multiple Inheritance
As described above, Vala while it is backed by C and GObject, can provide a limited multiple inheritance mechanism, by adding virtual methods to Interfaces. Is possible to add some ways to define default method implementations in interface implementor class and allow derived classes to override that methods.
If you define a virtual method in an interface and implement it in a class, you can't override interface's method without leaving derived classes unable to access to interface default one. Consider following code:
In this case, we have defined a Callable interface with a default implementation for abstract bool hang () called default_hang, it could be a static or virtual method. Then Caller is a base class implementing Callable for the TechPhone and Phone classes, while Caller'shang () method simple call Callable default implementation. TechPhone doesn't do anything and just takes Caller as base class, using the default method implementations; but Phone overrides Caller.hang () and this makes to use its own implementation, allowing to always call it even if it is cast to Callable object.
Explicit method implementation
The explicit interface method implementation allows to implement two interfaces that have methods (not properties) with the same name. Example:
Will output 10 bar.
Last updated