覆盖子类Swift中的静态var

时间:2015-11-30 10:50:54

标签: swift static override var

为了对我的代码进行分解,我想设置一个来自Child类的stringKey,我将在父类的类func中得到它:

Chair.request();
Table.request();

class Furniture: NSObject {

    static let requestKey : String!

    class func request(){

        print("class key => \(self.requestKey)")
        ...
    }
}

class Chair: Furniture {
    static let requestKey : String = "jsonchairs"
} 

class Table: Furniture {
    static let requestKey : String = "tables"
} 

当然,我有预编译的错误消息

  

属性不会覆盖其超类

中的任何属性

是否有解决方案可以执行此操作,还是需要将密钥作为参数传递?像这样:

Chair.request(key : "jsonchairs" );
Table.request(key : "tables" );

3 个答案:

答案 0 :(得分:5)

刚遇到同样的问题。使用计算属性 - 可以覆盖这些属性。

基类:

class BaseLanguage {
    class var language: String {
        return "Base"
    }

    static func getLocalized(key: String) -> String {
        print("language: \(language)");
    }
}

儿童班:

class German: BaseLanguage {
    override class var language: String {
        return "de"
    }
}

如果由于某种原因无法使用计算属性,则始终可以将变量属性包装在私有单例中。该类将外部接口公开为静态,但在其内部具有对其实例的静态私有引用。您可以在init方法中更改任何属性的值(只要它是变量)。

答案 1 :(得分:1)

我认为vale是正确的,在这种情况下通常会考虑协议。除了提供requestKey的协议定义之外,我还将request实现为协议的默认实现:

// define Furniture protocol

protocol Furniture {
    static var requestKey: String { get }
    static func request()
}

// implement default implementation in extension

extension Furniture {
    static func request() {
        print("class key => \(self.requestKey)")
    }
}

// both Chair and Table conform to this protocol

class Chair: Furniture {
    static let requestKey = "jsonchairs"
}

class Table: Furniture {
    static let requestKey = "tables"
} 

注意,我假设不需要Furniture基类,所以我选择了我的协议。您只需要决定是否真的需要这个Furniture基类。我从经过面向对象的编程过渡到面向协议的编程,我的经验法则是,是否可以存在此Furniture类型的具体实例,或者它是否更像是抽象/虚拟类型仅用于定义最终将被实例化的其他类型的某些共享行为(即ChairTable类型)。

如果Furniture确实是具体类型,那么您必须找到一种方法来实现您想要的而不使用static类型或方法,因为您无法覆盖静态。如果您向我们展示除了FurnitureChair类型之外您使用此Table类型的方式,我们也许可以帮助您以这样的方式重构不需要static方法/类型。

但是如果Furniture不是具体类型,那么我建议你自己去看看你是否可以通过协议完成所需的一切。当你从面向对象的编程转向面向协议的编程时,需要花一点时间来理解它。只是不要过于暴躁。有关详情,请参阅WWDC 2015 video Protocol-Oriented Programming in Swift或等效的WWDC 2016 video Protocol and Value Oriented Programming in UIKit Apps

顺便说一句,即使您采用这种面向协议的模式,我也不会倾向于在您的特定示例中使用static类型/方法,但这是一个单独的问题。上述面向协议的模式对于static方法同样适用于例如方法。

答案 2 :(得分:0)

您可以使用协议。只需使它们都符合RequestKeyProtocol fir示例,并在每种情况下都实现它。

protocol RequestKeyProtocol {
 var requestKey: String
}




 class myClass: RequestKeyProtocol {
   var requestKey = "myKey"
   }

如果您需要默认值,请查看协议扩展。 Take a look at this year WWDC video about protocols as well.