【问题标题】:How to avoid overriding superclass initializer如何避免覆盖超类初始化程序
【发布时间】:2018-01-14 05:35:17
【问题描述】:

我需要使用其超类GMSMarker 中的init 方法初始化Place 对象。问题是Place 还从BaseModel 继承了一个init 方法,以便我可以从JSON 创建对象。我以为我可以从BaseModel 的init 方法中调用GMSMarker 的init 方法,但不能。

地点

class Place: BaseModel, GMSMarker {
    var imageUrl: String
    var name: String
    required convenience init?(json: [String : AnyObject] {
        // super.init(markerWithPosition:) // can't call GMSMarker init method.  
    }
}

基础模型

protocol BaseModel {
    init?(json: [String : AnyObject])
    func toAnyObject() -> [String : AnyObject]?
}

GMSMarker 初始化定义

/** Convenience constructor for a default marker. */
+ (instancetype)markerWithPosition:(CLLocationCoordinate2D)position;

【问题讨论】:

  • First Place 没有从 BaseModel 继承任何东西,因为这是一个协议。地方必须符合 BaseModel 定义的 init 方法相同。其次,GMSMarker 中的方法不是初始化程序,它是一个工厂方法,像 GMSMaker.markerWithPosition 一样被调用。第三,即使它看到了初始化程序,您也需要使用参数来调用它,而不仅仅是参数的名称。
  • @UpholderOfTruth 先生,您没有提供任何建设性的解决方案。 Place 对象是否符合协议或从类继承(我错误地使用了术语),并不会改变 Place 包含给定 init 方法的事实。也许 Obj-C 工厂方法以某种方式快速转换为初始化程序。当我不符合BaseModel 时,我还能怎么打电话给Place(position: CLLocationCoordinate2D)?此外,“构造器”通常类似于“初始化器”。最后我知道你需要包含一个输入。为简洁起见,我将其省略了,因为它无论如何都无法识别。
  • 非常正确,这就是为什么它是评论而不是答案。阅读本文的人不知道您为了简洁而遗漏了什么,因此最好包含所有内容,以免对部分问题感到困惑。我只是想避免人们给你毫无意义的答案。例如,我可以说 GMSMarker 初始化定义是 ObjectiveC,但有些人可能没有意识到它,所以最好把它放在问题的某个地方。您没有提到您可以调用它,但也许显示 GMSMarker 的整个定义将有助于解决问题。还有什么错误?
  • 我也可以争辩说该评论是建设性的,但不是解决方案,因为您透露您可以致电Place(position: CLLocationCoordinate2D),这不在原始问题中。我只是想帮助你回答问题,但我总是可以继续做其他事情。
  • 我明白,并感谢您抽出时间为他人服务。问题是,在子类Place 中,我不能调用超类GMSMarker 的init 方法。我写了一个任意的例子来证明这一点,在这样做的同时,我发现我做错了什么。这得到了几票,所以我只能回答我自己。

标签: swift google-maps oop inheritance initialization


【解决方案1】:

创建一个调用超类 (GMSMarker) 的 init 方法的初始化程序并将值分配给任何其他属性,例如“名称”。然后在符合协议初始化器时,只需调用您创建的 self 的初始化器即可。

示例:

class Place: GMSMarker, BaseModel {
    var name: String
    // init
    init(lat: Double, long: Double, name: String) {
        // call init from GMSMarker superclass here.
        super.init(position: CLLocationCoordinate2D(latitude: self.lat, longitude: self.long))
        self.name = name
    }

    // BaseModel init
    required convenience init?(json: [String : AnyObject]) {
        guard let lat = json["lat"] as? Double, let long = json["long"] as? Double, let name = json["name"] as? Sring else {
            return nil
        }
        // call init method of self inside BaseModel init.
        self.init(lat: lat, long: long, name: name)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    相关资源
    最近更新 更多