interface A
{
void f();
}
interface B
{
void f();
}
class C : A ,B
{
// pseudocode
void A::a(){}
void B::a(){}
}
有没有办法有不同的实现方式A::f
,并B::f
在同一个班?
当它们具有相同的签名时,否*。如果A.f
isvoid f()
和B.f
is int f()
,则有可能。
*实际上,有一种方法,如果您接受它没有做完全相同的事情:
interface A { string f(); }
interface B { string f(); }
class C : A {
string f() { return "A"; }
string bf() { return "B"; }
// Pretend to be a B
alias get this;
B get() {
auto that = this;
return new class B {
string f() { return that.bf(); }
};
}
}
unittest {
auto c = new C();
A a = c;
B b = c;
assert(a.f() == "A");
assert(b.f() == "B");
}
在上面的代码中,我们alias this
用于创建一种第二继承链。这样做有一些问题,这是我们从get()
back到back返回的东西无法解决的最大问题C
。
使用UDA和mixin可以使它更通用,这样就可以编译并运行:
interface A { string f(); }
interface B { string f(); }
interface C { string f(); }
@implements!(B, C)
class D : A {
string f() { return "A"; }
@implements!(B.f)
string bf() { return "B"; }
@implements!(C.f)
string cf() { return "C"; }
mixin implement!();
}
unittest {
D d = new D();
A a = d;
B b = d;
C c = d;
assert(a.f() == "A");
assert(b.f() == "B");
assert(c.f() == "C");
assert(a == cast(A)d);
assert(b == cast(B)d);
assert(c == cast(C)d);
}
但是,这留给读者练习。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句