狗窝有一只狗。
KennelWithPlayground(Kennel类型)有一个DogWithABall(Dog类型),不能只有普通的Dog。
我希望能够像对待普通狗一样对待任何类型的狗窝。
因此,我想在子类中重新定义超类的属性。新属性将是该属性的超类的子类。在Dart中这可能吗? (可能类似于C#中的“新”修饰符)。还是有另一种方法可以实现这一目标?
下面的代码不起作用,因为在KennelWithPlayground类中,DogWithABall不是有效的Dog替代。
class Dog {
String get bark => "woof";
}
class DogWithBall extends Dog {
String get ballAction => "boing";
}
abstract class Kennel {
Dog dog;
}
class KennelWithPlayground implements Kennel {
DogWithBall dog; //**invalid override**
KennelWithPlayground(DogWithBall dog);
}
void processKennel(Kennel kennel){
kennel.dog.bark;
if (kennel is KennelWithPlayground)
print(kennel.dog.ballAction);
else
print("Bored dog");
}
答案 0 :(得分:3)
我可以想到两种解决方案。您可以使用covariant
关键字来允许覆盖,以牺牲运行时检查为代价,或者可以使用泛型来静态跟踪类型。对于前一种方法,您将更改Kennel
的定义,如下所示:
abstract class Kennel {
covariant Dog dog;
}
或者,更改KennelWithPlayGround
的定义:
class KennelWithPlayground implements Kennel {
covariant DogWithBall dog;
KennelWithPlayground(DogWithBall dog);
}
这将允许覆盖,但会在每次写入dog
字段时进行运行时检查,以确保所写入的内容实际上是DogWithBall
。
一种替代方法是按如下方式使用泛型:
class Dog {
String get bark => "woof";
}
class DogWithBall extends Dog {
String get ballAction => "boing";
}
abstract class Kennel<DogKind extends Dog> {
DogKind dog;
}
class KennelWithPlayground implements Kennel<DogWithBall> {
DogWithBall dog;
KennelWithPlayground(DogWithBall dog);
}
void processKennel(Kennel kennel){
kennel.dog.bark;
if (kennel is KennelWithPlayground)
print(kennel.dog.ballAction);
else
print("Bored dog");
}
答案 1 :(得分:1)
有可能,但前提是该属性没有设置器。
class Foo {
final num value;
Foo(this.value);
}
class Bar implements Foo {
final double value;
Bar(this.value);
}