我可以在子类中重新定义超类的属性吗? (也许是C#的新修饰符?)

时间:2019-08-06 10:55:33

标签: dart

狗窝有一只狗。

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");
}

2 个答案:

答案 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);
}