Dart 转换子类型失败
Dart 转换子类型失败,dart,Dart,(A()作为B.hello()导致类型转换中的类型“A”不是类型“B”的子类型 强制转换的工作方式是,您只能从更具体的类型(本例中为B)转到更一般的类型(a)。您创建的是a的实例,但a不是B。强制转换的工作方式是,您只能从更具体的类型(本例中为B)转到更一般的类型(a)。您创建的是a的实例,但A不是B。完全披露:我不知道Dart 您不能执行这种类型的强制转换,因为它可能会导致函数调用或字段访问没有得到很好的定义 我将更改您的示例以演示: class A { void hello() {
(A()作为B.hello()代码>导致类型转换中的类型“A”不是类型“B”的子类型
强制转换的工作方式是,您只能从更具体的类型(本例中为B)转到更一般的类型(a)。您创建的是a的实例,但a不是B。强制转换的工作方式是,您只能从更具体的类型(本例中为B)转到更一般的类型(a)。您创建的是a的实例,但A不是B。完全披露:我不知道Dart
您不能执行这种类型的强制转换,因为它可能会导致函数调用或字段访问没有得到很好的定义
我将更改您的示例以演示:
class A {
void hello() {
print('world');
}
}
class B extends A {
@override
void hello() {
print('StackOverflow');
}
}
现在如果您执行(A()作为B.hello2()代码>Dart应该做什么?这不是很明显,所以它不允许你这么做。走另一条路不是问题,因为B
继承了A
的所有内容
class A {
void hello() {
print('world');
}
}
class B extends A {
@override
void hello() {
print('StackOverflow');
}
void hello2() {
print('Is Great!');
}
}
另一个问题是类型为a
的值可能是a
的不同子类型,如C
完全公开:我不知道Dart
您不能执行这种类型的强制转换,因为它可能会导致函数调用或字段访问没有得到很好的定义
我将更改您的示例以演示:
class A {
void hello() {
print('world');
}
}
class B extends A {
@override
void hello() {
print('StackOverflow');
}
}
现在如果您执行(A()作为B.hello2()代码>Dart应该做什么?这不是很明显,所以它不允许你这么做。走另一条路不是问题,因为B
继承了A
的所有内容
class A {
void hello() {
print('world');
}
}
class B extends A {
@override
void hello() {
print('StackOverflow');
}
void hello2() {
print('Is Great!');
}
}
另一个问题是类型为a
的值可能是a
的不同子类型,如C
Dart通常允许您从超级类型向下转换为子类型,因为该值实际上可能是子类型
class A {
void hello() {
print('world');
}
}
class B extends A {
@override
void hello() {
print('StackOverflow');
}
}
class C extends A {
@override
void hello() {
print('Hello');
}
}
但是,Dart 2在一些情况下不允许向下转换,因为在某些情况下(甚至对编译器来说),强制转换在运行时总是失败的。这就是你在这里所说的:(A()作为B)
。A()
调用生成构造函数,因此编译器知道该表达式的类型正是A
(而不是A
的任何适当子类型)。因此,它知道在运行时将其强制转换为B
将始终失败,并且为了保护您自己,它完全不允许该程序。因此,会出现编译时错误。Dart通常允许您从超级类型向下转换为子类型,因为该值实际上可能是子类型
class A {
void hello() {
print('world');
}
}
class B extends A {
@override
void hello() {
print('StackOverflow');
}
}
class C extends A {
@override
void hello() {
print('Hello');
}
}
但是,Dart 2在一些情况下不允许向下转换,因为在某些情况下(甚至对编译器来说),强制转换在运行时总是失败的。这就是你在这里所说的:(A()作为B)
。A()
调用生成构造函数,因此编译器知道该表达式的类型正是A
(而不是A
的任何适当子类型)。因此,它知道在运行时将其强制转换为B
将始终失败,并且为了保护您自己,它完全不允许该程序。因此,出现了编译时错误。(动物()作为狗)
当Animal()
返回一个Cat
时会发生什么?问题不在于您正在调用.hello()
<代码>A()作为B
是问题所在。A不可能是“B”,因为A不扩展B,而作为“< /代码>”,C++中存在“<代码>虚拟方法表> /代码>,它可以用来查找方法B(及其A)。如果您确实需要进行转换,那么使用像C++这样的低级语言。但即使C++也阻止了STL的发展。这些语言让你可以将任何东西转换成任何东西,而这正是你想要做的
当Animal()
返回一个Cat
时会发生什么?问题不在于您正在调用.hello()
<代码>A()作为B
是问题所在。A不可能是“B”,因为A不扩展B,而作为“< /代码>”,C++中存在“<代码>虚拟方法表> /代码>,它可以用来查找方法B(及其A)。如果您确实需要进行转换,那么使用像C++这样的低级语言。但即使C++也阻止了STL的发展。这些语言允许您将任何内容转换为任何内容,而这正是您想要做的。@CreativeCreatorMorMaybenot:它不能添加不存在的其他方法A
没有Hello2()
,因此无需添加任何内容。您不能在A
中发明A
中不存在的功能。另一个方向的强制转换是有效的,因为B
继承了它的祖先的功能,但是A
不能继承B
@creativecreatorormaybenot:你不能。A
无法使用该数据。想想看:一个人可以把他的基因传给他的儿子,他的儿子继承了他的眼睛颜色,面部特征,甚至他的名字(Fred Jr)。但那个父亲不能走进理发店,说叫我小儿子,给我儿子理发,因为理发师不能通过父亲的头给儿子理发。如果你需要做你所要求的,你的课程设计不正确,你应该考虑重新设计。在父级(A
)中具有默认行为,并覆盖它以在B
中执行您想要的操作。您可以使用适配器模式,或者只是将A包装在某个内容中new@creativecreatorormaybenot:无法添加不存在的其他方法A
没有Hello2()
,因此无需添加任何内容。您不能在A
中发明A
中不存在的功能。另一个方向的强制转换是有效的,因为B
继承了它的祖先的功能,但是A
不能继承B
@creativecreatorormaybenot:你不能