为什么我必须强制将数组对象向下转换为swift中的子类
我有以下——简化的——代码: 在swift 2.1中,我必须使用as!或者我得到一条错误消息,A不能转换为B。我应该强制转换到子类,这似乎是错误的,但也许我遗漏了什么 注释掉的部分是我的第一次尝试,但它也不能用类型为“[B]”的消息myList编译,不能重写类型为“[a]”的属性 在这两种情况下,我都不理解这种行为,因为B显然是a的一个子类为什么我必须强制将数组对象向下转换为swift中的子类,swift,Swift,我有以下——简化的——代码: 在swift 2.1中,我必须使用as!或者我得到一条错误消息,A不能转换为B。我应该强制转换到子类,这似乎是错误的,但也许我遗漏了什么 注释掉的部分是我的第一次尝试,但它也不能用类型为“[B]”的消息myList编译,不能重写类型为“[a]”的属性 在这两种情况下,我都不理解这种行为,因为B显然是a的一个子类 有人能解释为什么我不能推翻声明吗 有人能解释一下我为什么要强迫他们失望吗 谢谢 对于点(1),您根本无法覆盖存储的属性,只能覆盖计算的属性。此外,即使重写计
int
和子类中的int
,或者是超类中的[A]
和子类中的[A]
,那么您实际上没有通过重写它来更改任何内容。您可以通过重写计算属性来更改行为,但显然不能使用存储属性,因此这样做没有什么意义
对于第(2)点,您必须强制向下转换,因为您试图访问超类中不存在的属性,即y
。如果希望通过超类引用访问子类,则必须将自己限制为该超类提供的接口A
没有y
属性,因此当bar
为A
类型时,尝试访问bar.y
没有意义-必须将其向下转换为B
类型才能执行此操作
在OOP中,向上转换通常很容易,因为我们从继承结构中知道,B
是一个A
,所以用这种方式转换很简单。但相反的方向,情况并非如此——当B
继承自A
时,AB
就是A
,但A
不是B
。因此,当你从A
向下转换为B
时,你必须明确地这样做,因为如果你转换的东西根本不是AB
,就会发生坏事
顺便说一句,您不必使用as强制向下播放代码>-您可以使用作为?
安全地进行尝试,例如:
if let bar = mylist[2] as? B {
print(bar.y)
}
else {
print("not a B!")
}
编译器如何知道myList
包含B
?在几乎任何语言中,您都必须显式地向下转换(转换为子类)。在java或C++中也是这样。我明白你必须明确地下注,这不是我的问题。我的问题是为什么我必须添加!强制向下播放。错误不是在访问y时发生的。错误在编译器让我在!对于as,这似乎有点过分,因为B是a的子类,myList被声明为a的数组。
if let bar = mylist[2] as? B {
print(bar.y)
}
else {
print("not a B!")
}