转换子类型失败

时间:2018-07-27 22:39:10

标签: dart

class A {
  void hello() {
    print('world');
  }
}

class B extends A {
  @override
  void hello() {
    print('StackOverflow');
  }
}

(A() as B).hello();产生type 'A' is not a subtype of type 'B' in type cast

3 个答案:

答案 0 :(得分:1)

强制转换的工作方式是,您只能从更具体的类型B(在这种情况下为B)变为更一般的类型A。您创建A的实例,但A不是B。

答案 1 :(得分:1)

完全公开:我不认识达特。

您不能进行这种类型的转换,因为它可能导致函数调用或字段访问定义不正确。

我将更改您的示例以进行演示:

class A {
    void hello() {
         print('world');
    }
}


class B extends A {
    @override
    void hello() {
        print('StackOverflow');
    }
    void hello2() {
        print('Is Great!');
    }
}

现在,如果您执行(A() as B).hello2();,Dart应该怎么做?这并不是很明显,因此不允许您这样做。因为B继承了A的所有内容,所以采用其他方法不是问题。

class A {
    void hello() {
         print('world');
    }
}


class B extends A {
    @override
    void hello() {
        print('StackOverflow');
    }
}

class C extends A {
    @override
    void hello() {
        print('Hello');
    }
}

另一个问题是类型为A的值可能是A的另一个子类型,例如C

答案 2 :(得分:0)

Dart通常允许您从超级类型向下转换为子类型,因为该值实际上可能是该子类型。

Animal animal = Cat();
if (something) animal = Dog();
...
Cat cat = animal as Cat; // Allowed, the animal may be a cat.

但是,在某些情况下(即使对于编译器而言),显而易见(在编译器中),Dart 2不允许向下转换,强制转换将始终在运行时失败。这就是您要点击的位置:(A() as B)A()调用生成式构造函数,因此编译器知道表达式的类型完全是 A(而不是A的任何适当子类型) 。因此,它知道强制转换为B总是会在运行时失败,并且出于您自己的保护,它完全禁止该程序。因此,出现了编译时错误。