Решением для этого в Котлине является делегирование .
Вы можете сделать это множеством способов, и это зависит от ваших потребностей, какой из них вы должны выбрать.Сначала вам понадобится interface
для вашего Composite
:
interface Composite {
val one: Int
val two: Int
}
и реализация по умолчанию:
class DefaultComposite(override val one: Int,
override val two: Int) : Composite
Затем вы можете использовать ключевое слово by
для делегированияэкземпляр Composite
из Host
:
class Host(val composite: Composite) : Composite by composite
Если у вас есть разумные значения по умолчанию для composite
:
class CompositeWithDefaults(override val one: Int = 1,
override val two: Int = 2) : Composite
, вам даже не нужно проходить Composite
в качестве параметра конструктора:
class Host() : Composite by CompositeWithDefaults()
или вы можете передать его поля в Host
:
class Host(one: Int, two: Int) : Composite by DefaultComposite(one, two)
или иметь для него значение по умолчанию:
class Host(composite: Composite = CompositeWithDefaults()) : Composite by composite
Будьте осторожны: вы не должны делегировать свойству, которое является изменяемым, потому что байт-код, сгенерированный при использовании by
, будет использовать внутреннее поле для вашего делегата, и замена исходного объекта не будет иметь никакого эффекта .Я написал об этом здесь .
Вот как будет выглядеть сгенерированный код Java, если бы composite
был var
:
public final class Host implements Composite {
@NotNull
private Composite composite;
// $FF: synthetic field
private final Composite $$delegate_0;
@NotNull
public final Composite getComposite() {
return this.composite;
}
public final void setComposite(@NotNull Composite var1) {
Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
this.composite = var1;
}
public Host(@NotNull Composite composite) {
Intrinsics.checkParameterIsNotNull(composite, "composite");
super();
this.$$delegate_0 = composite;
this.composite = composite;
}
public int getOne() {
return this.$$delegate_0.getOne();
}
public int getTwo() {
return this.$$delegate_0.getTwo();
}
}
Примечаниечто установщик не устанавливает $$delegate_0
, но composite
.