【问题标题】:Swift: declaration 'description' cannot override more than one superclass declarationSwift:声明“描述”不能覆盖多个超类声明
【发布时间】:2014-08-19 00:19:17
【问题描述】:

我有一个类似于下面的继承结构。我正在采用 Printable 协议并努力覆盖 description 属性。我遇到了一个奇怪的错误,此时谷歌似乎不知道,提示输入第三类,并引用第二类和第一类。

雪上加霜,下面的代码实际上编译得很好,但我的完整代码没有。在 Second 和 Third 上注释属性可以解决问题,代码编译、测试通过等。

Swift 继承章节提供了指向 this 的指针。

有谁知道它的含义以及触发它的情况?

/Users/ivanhoe/Dropbox/swift/convergence/Processable.swift:124:18: 错误:声明“描述”不能覆盖多个 超类声明 覆盖 var 描述:字符串 { ^ /Users/ivanhoe/Dropbox/swift/convergence/Processable.swift:85:18: 注意:覆盖的声明在这里 覆盖 var 描述:字符串 { ^ /Users/ivanhoe/Dropbox/swift/convergence/Processable.swift:28:18: 注意:覆盖的声明在这里 覆盖 var 描述:字符串 {

import Foundation

class First : NSObject, Printable {

    override var description : String {
        return "first"
    }
}

class Second : First {

    override var description : String {
        return "second"
    }

}

class Third : Second {

    override var description : String {
        return "third"
    }

}

println(Third())

【问题讨论】:

  • "下面的代码实际上编译得很好" 然后你应该把它变成它不再编译的状态。我知道,这听起来很奇怪,因为通常你会走另一条路,但如果你想显示错误,你需要损坏的代码。
  • 我同意,但我显然做不到。这就是我在上面的模型上从头开始的原因。我问了一个关于错误消息的具体问题,该错误消息看起来很明确,但在野外完全未知/未观察到。
  • 它是 NSObject 的子类对您来说很重要吗?为什么?
  • 目前对我的代码没有真正的影响,可以安全地跳过,对错误也没有影响,但我试图准确地表示错误情况
  • 更正:NSObject 可以使 XCTAssertEqual 之类的断言起作用,因为我正在使用 TDD 开发一些东西......当然我可以只使用 XCTAssert 等,但这并不是真正的重点问题

标签: clang swift


【解决方案1】:

在覆盖 SKTiledScene 时,我遇到了与 SKTiled 相同的问题。在我的情况下,我想覆盖 OS X 的鼠标事件。

错误如下:

Declaration 'mouseUp(with:)' cannot override more than one superclass declaration

这里的问题是鼠标事件是在类扩展中声明的:

#if os(macOS)
extension SKTiledScene {

    override open func mouseDown(with event: NSEvent) {}

    override open func mouseMoved(with event: NSEvent) {
        guard let cameraNode = cameraNode else { return }
        cameraNode.mouseMoved(with: event)
    }
    override open func mouseUp(with event: NSEvent) {}
    override open func mouseEntered(with event: NSEvent) {}
    override open func mouseExited(with event: NSEvent) {}

    override open func scrollWheel(with event: NSEvent) {
        guard let cameraNode = cameraNode else { return }
        cameraNode.scrollWheel(with: event)
    }
}
#endif

我可以通过重新实现扩展来解决我的问题,以覆盖我自己的 SKTiledScene 子类中的方法:

extension SKTiledScene {
    open override func mouseUp(with event: NSEvent) {
        try! SceneManager.shared.transitionToScene(MainMenuScene.self, withAnimation: .fade)
    }
}

我想知道我是否可以确定我的扩展总是被加载而不是来自 SKTiled 框架的那个,但它现在似乎运行良好。

【讨论】:

    【解决方案2】:

    什么是可打印协议? ;-)

    您可以将属性的 Getter 用作

    var description: String {
        get {
            return "This is a test";
        }
    }
    

    【讨论】:

    • 这应该被标记为正确答案。这会覆盖 NSObjectProtocol 中的 getter。这样它在打印到控制台时使用描述字符串。
    • 现在改用 CustomStringConvertible 协议
    【解决方案3】:

    对我来说同样的问题,通过这样做解决了:

    func customDescription() -> String {
        return ""
    }
    
    override var description: String {
        return customDescription()
    }
    

    因此您可以根据需要多次覆盖函数

    【讨论】:

    • 它运行良好(我还不明白为什么,离 Swift 不远了),而且似乎你甚至可以跳过 customDescription 函数声明,直接从 @ 返回你想要的结果987654323@.
    【解决方案4】:

    我现在无法访问我的 Mac,但我会尝试删除 First 中的 override。子类化时需要override,但实现protocol 时不需要。

    【讨论】:

    • 没用。当您尝试覆盖已覆盖的属性时,您会收到错误消息。看来编译器只能处理一个覆盖。
    • @Alexander 不确定了。那是三年前。它现在似乎已修复。
    • @devios1 哦,哈哈,没想到这个问题这么老了。一定有人评论过它并抛弃了它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-03
    • 2019-10-15
    • 2016-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-28
    相关资源
    最近更新 更多