2017-08-03 27 views
-5

我想知道的扩展类和简单的类之间一致的协议(除可读性什么是扩展的使用符合协议

想我已经创建的类的确切差异具有实现代码如下方法,如

class DemoVC:UIViewController,UITableViewDelegate,UITableViewDataSource 
{ 
    //MARK: - 
    //MARK: - UITableview delegate 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    { 
     return 0 
    } 
    func numberOfSections(in tableView: UITableView) -> Int { 
     return 1 
    } 
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

     ... 

    } 
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    { 
     ... 
    } 

//Other codes 
} 

,而不是如果我创建相同的类扩展到符合的tableView方法类似

extension DemoVC:UITableViewDelegate,UITableViewDataSource 
{ 
    //MARK: - 
    //MARK: - UITableview delegate 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    { 
     return 0 
    } 
    func numberOfSections(in tableView: UITableView) -> Int { 
     return 1 
    } 
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    .... 
} 
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    { 
    } 
} 

那么哪个更好,为什么(except READABILITY)

第二个例子 随着双扩展性好

extension Double { 
     var mm: Double { return self/1_000.0 } 
    } 
    let oneInch = 25.4.mm 
    print("One inch is \(oneInch) meters") 

或者

let oneInch = 25.4./1000 

所以在这里我想问哪个更好用的双扩展名或者我有简单的分裂加倍1000(如果我需要在特定的类只)为什么?

+3

我相信这是可读性,没有别的。 –

+0

好吧,如果你想在你的扩展中使用类中的'private'属性,你必须将它改为'fileprivate'(只要扩展名在同一个文件中) – Keiwan

+0

@Keiwan I' d要注意的是,你提到的对于Swift 3来说是正确的,在Swift 4中,扩展可以访问私人访问控制,请检查我关于此主题的答案:https://stackoverflow.com/questions/24003918/does-swift-have - 访问修饰符/ 39697920#39697920(“Swift 3和Swift 4访问控制之间有什么区别?”);) –

回答

0

其可读性和访问。如果你在同一个类和文件中符合,实现对类的其他变量和函数的访问级别不同,而如果在不同的文件中定义,它将具有不同的访问级别。

1

扩展名与Objective-C中的类别相似。 (与Objective-C类别不同,Swift扩展没有名称。)

扩展可以扩展现有类型以使其采用一个或多个协议。要添加协议一致性,你写的协议名称相同的方式,你写出来的一类或结构

extension someClassName: OneProtocol, AnotherProtocol { 
    // implementation of protocol requirements goes here 
} 
+0

@JaydeepVyas我以为你错过了一些好东西扩展是exsisting功能添加exsisting类,但你不能覆盖现有的功能(如预先定义) –

+0

请注意,您可以添加计算属性扩展,Objective-C类别不能有属性... –

+0

@Ahmad F yea of​​course我错过了那一点 –

0

在问候斯威夫特3,当你使用扩展你没有访问私有方法和结构在扩展类中。所以如果你的数据模型是私有的,你不能通过扩展来访问它,如果你实现了表视图方法,你很可能会想要这样做。

关于Swift 4,唯一需要扩展的时间是当你无法访问正在扩展的类的源。在Swift 4中,私有数据可以通过在同一个文件中定义的扩展来访问,在这种情况下,任何一种方式都可以工作。

遵循的经验法则:如果您有权访问类源并允许修改它,那么只需在类中直接遵守协议即可。如果您没有源代码或者您不允许修改源代码,那么您将需要使用扩展名。

除此之外,唯一的主要区别是可读性,正如您已经提到过的,所以它归结为风格问题,等待您的设计不需要访问私人数据。

+0

请注意,这个逻辑已被编辑在* Swift 4 *中,请检查:https://stackoverflow.com/questions/24003918/does-swift-have-访问修饰符/ 39697920#39697920(“Swift 3和Swift 4 Access Control之间有什么区别?”) –

+0

@AhmadF谢谢!这很好。 – gregpaton08

+0

@JaydeepVyas对不起,我的回答是关于Swift 3,而不是Swift 4.你的答案没有指定。我会更新我的答案。 – gregpaton08

0

在以下extension我们使用的是继承的概念。

extension DemoVC:UITableViewDelegate,UITableViewDataSource 
{ 
    //MARK: - 
    //MARK: - UITableview delegate 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    { 
     return 0 
    } 
    func numberOfSections(in tableView: UITableView) -> Int { 
     return 1 
    } 
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    .... 
} 
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    { 
    } 
} 

而下面extension是一个类中的添加更多的功能。

extension Double { 
     var mm: Double { return self/1_000.0 } 
    } 
    let oneInch = 25.4.mm 
    print("One inch is \(oneInch) meters") 

extension Double {}我们可以在一个项目内的任何类使用。意思就是我们必须调用像let oneInch = 25.4.mm这样的方法。

+0

我认为扩展中的方法还不能被覆盖,所以至少我们不使用继承的概念 –