gpt4 book ai didi

swift - 为什么我必须在 swift 中强制将数组对象向下转换为子类

转载 作者:搜寻专家 更新时间:2023-11-01 05:37:09 25 4
gpt4 key购买 nike

我有以下——简化的——代码:

class A {
var x: Int = 9

}

class B: A {
var y: Int = 8
}


class S {
var myList = [A]()
}


//class T: S {
// override var myList = [B]()
//}

class V: S {

func foo() {
let bar = myList[2] as! B
print(bar.y)
}
}

在 swift 2.1 中,我必须使用 as!或者我收到 A 不可转换为 B 的错误消息。我应该强制转换为子类似乎是错误的,但也许我遗漏了一些东西。

注释掉的部分是我的第一次尝试,但它也没有编译消息 myList with type '[B]' cannot override a property with type '[A]'

在这两种情况下,我都不理解这种行为,因为 B 显然是 A 的子类。

  1. 有人可以解释为什么我不能覆盖声明吗?
  2. 谁能解释一下我为什么要强制情绪低落?

谢谢!

最佳答案

对于第 (1) 点,您根本无法覆盖存储的属性,只能覆盖计算的属性。此外,即使您重写了一个计算属性,您也不能像您在此处尝试那样给它一个不同的类型。由于您无法更改类型,因此覆盖存储的属性实际上没有任何意义 - 您将如何覆盖它?如果它是 int在父类(super class)和一个int在子类中,或 [A]在父类(super class)和 [A] 中在子类中,那么您实际上并没有通过覆盖它来改变任何东西。您可以通过覆盖计算属性来更改行为,但显然不能使用存储属性,因此这样做意义不大。

对于第 (2) 点,您必须强制进行向下转换,因为您正试图访问一个属性 - 即 y - 父类(super class)中不存在。如果要通过父类(super class)引用访问子类,则必须限制自己使用该父类(super class)提供的接口(interface)。 A没有 y属性(property),所以试图访问bar.y什么时候bar类型为 A没有意义 - 你必须向下转换为类型 B这样做。

通常在 OOP 中,向上转换通常很容易,因为我们从继承结构中知道 B是一个 A ,因此以这种方式转换它很简单。但是相反的方向却不是这样——当B继承自 A , 然后是 B是一个 A ,而是一个 A不是 B .因此,当您从 A 向下转换时至 B , 你必须明确地这样做,因为如果你正在转换的东西结果不是 B 就会发生不好的事情。完全没有。

顺便说一下,您不必强制使用as! 进行沮丧。 - 你可以安全地尝试 as? ,例如:

if let bar = mylist[2] as? B {
print(bar.y)
}
else {
print("not a B!")
}

关于swift - 为什么我必须在 swift 中强制将数组对象向下转换为子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35567970/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com