2017-09-04 89 views
3

我有點搞砸具有以下概念:繼承的類Vs的協議

代碼1:

class New{ 
    func abc(){ 
     print("new class") 
    } 
} 

class ClassNew: New { 
    override func abc() { 
     print("derived class") 
    } 
} 

代碼2:

protocol New{} 

extension New{ 
    func abc(){ 
     print("new protocol") 
    } 
} 

class ClassNew: New { 
    func abc() { 
     print("derived protocol") 
    } 
} 
  1. Code 1Code 2之間有什麼區別,因爲它們都有相同的作用?

  2. code 2classNew距離新的協議inheriting或只是conforming到協議?

任何解釋將不勝感激!

+0

類或協議應該有更好的命名,例如'MyClass'而不是'myClass'。 –

+0

更改名稱,完成! –

+1

看到這個簡單的視頻:[Protocol-Oriented Views](https://www.youtube.com/watch?v=AySlYrel7fc),並閱讀[什麼是面向協議的編程在Swift中?它帶來了什麼附加值?](https://stackoverflow.com/questions/37530346/what-is-protocol-oriented-programming-in-swift-what-added-value-does-it-bring) – Honey

回答

3

代碼1和代碼2基本上是不一樣

代碼1和代碼2之間的區別是什麼,因爲他們都服務於相同的目的?

不,他們沒有。第一個定義了一個類層次結構,第二個定義了一個協議(一個API,如果你喜歡的話)和一個符合它的類型。

在代碼2中,classNew是從新協議繼承還是僅僅符合協議?

它符合協議。沒有涉及的繼承(如果你是迂腐)。


代碼1定義了一個基類和一個繼承自它的類。子類覆蓋了基類的功能abc()和它的行爲,你會期望給一個類層次結構,即

let x: New = ClassNew() 
let y: ClassNew = ClassNew() 

print(x.abc()) // prints "derived class" 
print(y.abc()) // prints "derived class" 

兩個打印語句調用abc()

派生類的在碼2你定義一個協議沒有方法,並使用擴展方法擴展協議。請注意,這是而不是一個「默認方法」在協議中沒有任何內容默認。然後定義一個符合協議的類,並添加一個恰好與擴展方法名稱相同的新方法。因爲abc()所謂的版本是在編譯時

protocol New2{} 

extension New2{ 
    func abc(){ 
     print("new protocol") 
    } 
} 

class ClassNew2: New2 { 
    func abc() { 
     print("derived protocol") 
    } 
} 

let y2: ClassNew2 = ClassNew2() 
let x2: New2 = y2 

print(x2.abc()) // prints "new protocol" 
print(y2.abc()) // prints "derived protocol" 

即使X2和Y2 是同一對象不同功能的版本被稱爲靜態確定的區別(從單純的類層次結構)是很重要的。這是因爲編譯器不允許假定x2的任何內容,除非它能從協議中推斷出來。所以它不知道該對象有自己的abc(),所以它必須調用擴展函數。

如果您已經定義的協議是這樣的:

protocol New3{ 
    func abc() 
} 

extension New3{ 
    func abc(){ 
     print("new protocol") 
    } 
} 

class ClassNew3: New3 { 
    func abc() { 
     print("derived protocol") 
    } 
} 

let y3: ClassNew3 = ClassNew3() 
let x3: New3 = y3 

print(x3.abc()) // prints "derived protocol" 
print(y3.abc()) // prints "derived protocol" 

這一次的編譯器知道對象應該具有的功能ABC(),如果它不只會使用擴展功能。然後,類的正常繼承規則適用。

1

classNew簡單地說是符合第二代碼中的協議。 Swift中的每個協議都是如此,因爲繼承是目前不支持帶協議的

這也回答了你的第一個問題:有在這種使用情況下,兩個碼之間沒有顯著差異,但一般來說,協議有利於其他類型的東西比子類。

+0

但是實現協議是一種實現多重繼承的方法,那麼在單一繼承的情況下它是不是真的? –

+2

@ShubhamMishra協議完全與繼承無關。 – Fogmeister

+0

看到這個鏈接@Fogmeister:https://stackoverflow.com/questions/41054396/can-i-able-to-support-multiple-inheritance-with-protocol-in-swift –

1

Code 1Code 2完全相同,只是概念上不同而已。

如果我們用簡單的話來說,Class定義了對象本身,而Protocol定義了對象的行爲。

如果與Java相比,類似於Interfaces

Checkout the Protocol Documentation

+0

不,它們不一樣。 – JeremyP

1

代碼2protocol extensions一個例子。最大的區別是你不能撥打super.abc()代碼2 - 你必須提供一個方法實現,它不在任何super上下文中。

只是我的看法 - 不要使用協議默認實現,因爲如果你真的需要時忘記提供「覆蓋」,編譯器將不會保存你。

+0

這不是默認實現。該協議聲明沒有功能默認。 – JeremyP

+0

@JeremyP你是對的,這是一個純粹的擴展 –