首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么下课失败了,但升职成功了?

为什么下课失败了,但升职成功了?
EN

Stack Overflow用户
提问于 2021-12-13 19:13:50
回答 2查看 97关注 0票数 -1

我有以下课程:

代码语言:javascript
复制
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来对待。我的理解是,我应该沮丧,就像这样:

代码语言:javascript
复制
let someShape = Shape(name: "Test shape")
let rect = someShape as! Rectangle

这是失败的。来自Xcode:

无法将“形状”(0x103c76910)类型的值转换为“矩形”(0x103c76530)

如果我从一个Rectangle开始,向上转换到一个Shape,然后向下转换回Rectangle,那么它是有效的:

代码语言:javascript
复制
let rect = Rectangle(name: "Test rect")
let someShape = rect as! Shape
let downcastRect = someShape as! Rectangle

为什么我的第一次失败,而第二次失败?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-12-13 19:26:23

当转换类型时,实例不会改变。实例是存储在内存中的实际分配对象。变量只是对实例的引用。

在第一个例子中,实例是一个Shape。引用实例的变量不能是Rectangle类型。

在第二个例子中,实例是一个Rectangle。当它转换到一个Shape时,实例someShape引用仍然是一个Rectangle。这允许将someShape转换回Rectangle

票数 2
EN

Stack Overflow用户

发布于 2021-12-13 19:18:34

原因很简单--向上转换和下播不会改变实例的类型,它只会更改变量的类型。

在第一种情况下,您有一个Shape实例,因为并非所有形状都是矩形,因此不能将其转换为Rectangle

在第二个例子中,您从Rectangle的一个实例开始,该实例存储在一个Shape变量中。但是,实例仍然是一个Rectangle。当然,您可以将其降回Rectangle,因为它仍然是一个Rectange。如果您尝试将其转换为不同的形状,例如Triangle,则该转换将失败。

这就是为什么我们有像isas?这样的运营商。在第一种情况下:

代码语言:javascript
复制
let someShape = Shape(name: "Test shape")
print(someShape is Rectangle) // false - this is not a Rectangle

在第二种情况下:

代码语言:javascript
复制
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安全地进行转换,或者直接写:

代码语言:javascript
复制
let someShape: Shape = rect
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70339793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档