【问题标题】:Subclassing v.s. Protocols子类化与协议
【发布时间】:2015-11-04 15:04:38
【问题描述】:

让我们从Class 方法开始:

class LoginCredentials {

    var id : String

    init(userID:String) {
        self.id = userID
    }
}

那么我们将有以下内容:

class FacebookLoginCredentials : LoginCredentials {

var token : String
init(userID:String,userToken:String) {

    self.token = userToken    
    super.init(userID: userID)
}}

class TwitterLoginCredentials  : LoginCredentials {
var token : String
var secret : String
init(userID:String,userToken:String,secret : String) {

    self.token = userToken
    self.secret = secret
    super.init(userID: userID)
}
}

如果我没记错的话,第二种方法是Protocol Oriented

protocol LoginCredentials {

    var id : String { get }
}

然后我们将有:

struct FacebookLoginCredentials : LoginCredentials {

var id: String
var token : String
init(userID:String,userToken:String) {

    self.id = userID
    self.token = userToken
}
}

struct TwitterLoginProfile : LoginCredentials {
var id: String
var token : String
var secret : String

init(userID:String,userToken:String,secret : String) {

    self.token = userToken
    self.secret = secret
    self.id = userID
}
}

我只需要知道哪个更 Swift 吗?

【问题讨论】:

标签: ios swift macos protocols


【解决方案1】:

最终,这些方法都不是“更 Swift”。在 Swift 中,有时您会想要使用继承,有时您会想要使用协议。这两种方法的真正决策点是:

您想要值类型语义(结构和协议)还是引用类型语义(类和协议)。我通常默认使用值类型语义,因为它们更安全,但在某些情况下引用类型语义很重要。您可以在此处阅读更多相关信息:Why Choose Struct over Class

【讨论】:

    【解决方案2】:

    要么 要么 在 swift 中是可以接受的。

    以下是您想要区分两者的方式。

    使用协议时,您希望将它们视为对象的蓝图。

    Ballplayers must know what a ball is, so any person that wants to be a Ballplayer must know what a ball is.

    你有一套你希望某些对象遵循的规则,制定一个协议。

    如果你想制作具有功能的对象,并且你希望孩子们继承这个功能,然后拥有更多的功能,那就做 inheret 类结构。

    Dad can throw a ball at 100MPH Junior can throw a ball at 100MPH and throw a curve ball.

    这将通过一个类而不是协议来完成

    【讨论】:

    • 这个答案似乎没有包含任何关于协议扩展的想法。仍然可以向协议添加功能,只是不能使用继承。
    • 那是因为扩展协议超出了协议的作用,这就是为什么它在扩展中完成
    【解决方案3】:

    结构实例总是按值传递,类实例总是按引用传递。这意味着它们适用于不同类型的任务。在考虑项目所需的数据结构和功能时,请决定每个数据结构应定义为类还是结构。

    作为一般准则,请考虑在满足以下一个或多个条件时创建结构:

    该结构的主要目的是封装一些相对简单的数据值。 当您分配或传递该结构的实例时,期望封装的值将被复制而不是引用是合理的。 结构存储的任何属性本身都是值类型,它们也应该被复制而不是引用。 该结构不需要从另一个现有类型继承属性或行为。 结构的良好候选者示例包括:

    • 几何形状的大小,可能封装了一个宽度属性和一个高度属性,两者都是 Double 类型。
    • 一种引用系列中范围的方法,可能封装了一个起始属性和一个长度属性,两者都是 Int 类型。
    • 3D 坐标系中的一个点,可能封装了 x、y 和 z 属性,每个属性都是 Double 类型。

    在所有其他情况下,定义一个类并创建该类的实例 通过引用进行管理和传递。在实践中,这意味着 大多数自定义数据构造应该是类,而不是结构。

    Why Choose Struct Over Class?

    【讨论】:

      猜你喜欢
      • 2017-10-12
      • 1970-01-01
      • 1970-01-01
      • 2012-05-29
      • 2015-05-25
      • 1970-01-01
      • 2011-07-07
      • 1970-01-01
      • 2015-07-06
      相关资源
      最近更新 更多