我有以下课程:
class Shape {
var name: String
var area: Int?
init(name: String) {
self.name = name
}
}
class Rectangle : Shape {
public func calculateArea(width: Int, height: Int) {
self.area = width * height
}
}我得到了一个Shape,我决定把它作为一个Rectangle来对待。我的理解是,我应该沮丧,就像这样:
let someShape = Shape(name: "Test shape")
let rect = someShape as! Rectangle这是失败的。来自Xcode:
无法将“形状”(0x103c76910)类型的值转换为“矩形”(0x103c76530)
如果我从一个Rectangle开始,向上转换到一个Shape,然后向下转换回Rectangle,那么它是有效的:
let rect = Rectangle(name: "Test rect")
let someShape = rect as! Shape
let downcastRect = someShape as! Rectangle为什么我的第一次失败,而第二次失败?
发布于 2021-12-13 19:26:23
当转换类型时,实例不会改变。实例是存储在内存中的实际分配对象。变量只是对实例的引用。
在第一个例子中,实例是一个Shape。引用实例的变量不能是Rectangle类型。
在第二个例子中,实例是一个Rectangle。当它转换到一个Shape时,实例someShape引用仍然是一个Rectangle。这允许将someShape转换回Rectangle。
发布于 2021-12-13 19:18:34
原因很简单--向上转换和下播不会改变实例的类型,它只会更改变量的类型。
在第一种情况下,您有一个Shape实例,因为并非所有形状都是矩形,因此不能将其转换为Rectangle。
在第二个例子中,您从Rectangle的一个实例开始,该实例存储在一个Shape变量中。但是,实例仍然是一个Rectangle。当然,您可以将其降回Rectangle,因为它仍然是一个Rectange。如果您尝试将其转换为不同的形状,例如Triangle,则该转换将失败。
这就是为什么我们有像is和as?这样的运营商。在第一种情况下:
let someShape = Shape(name: "Test shape")
print(someShape is Rectangle) // false - this is not a Rectangle在第二种情况下:
let rect = Rectangle(name: "Test rect")
let someShape = rect as! Shape
print(someShape is Rectange) // true - someShape is still a Rectangle还请注意,您对rect as! Shape有一个警告。编译器知道每个Rectangle都是一个Shape,您可以使用rect as Shape安全地进行转换,或者直接写:
let someShape: Shape = recthttps://stackoverflow.com/questions/70339793
复制相似问题