2017-06-12 57 views
0

我有一個函數,它需要一個類型爲Being的實例。有Being有兩個亞類:PersonAnimal。我希望函數能夠識別哪個被傳遞,並且針對每個子類使用特定的屬性。將超類作爲其中一個子類投射

我想這會工作:

func fight(attacker1: Being, attacker2: Being) -> String { 
    if attacker1 is Person { 
     let name1 = attacker1.name as! Person //Error: Value of type Being has no member name 
    } else { 
     print("Its not a person") 
    } 

但事實並非如此。什麼是最順利/最短的方式來實現我在找什麼?

+0

在這種情況下,爲什麼不使用基類中的名字? (因爲動物和人都可以有名字) – giorashc

+0

'attacker1.name as!人'這是錯誤的,請看[V.Khambirs'Ans](https://stackoverflow.com/a/44493238/5546312) – D4ttatraya

+0

@giorashc他們不能。它是名稱或物種。根據交給該職能的班級,它需要知道要求哪一個。 – Marmelador

回答

1

儘管@ V.Khambir的代碼有效,可能是更好的解決方案,但並沒有指出你的代碼問題。您正試圖將.name轉換爲Person.name不是attacker1的財產,這就是爲什麼你會收到錯誤。你想要做的是投attacker1Person,然後訪問名稱屬性。

func fight(attacker1: Being, attacker2: Being) -> String { 
    if attacker1 is Person { 
     let name1 = (attacker1 as! Person).name 
    } else { 
     print("Its not a person") 
    } 
+0

由於這個答案更具體地代表我的問題,我已經標記爲正確的。 – Marmelador

+0

這不會使用Swift最佳實踐,因爲您實際上正在執行兩次......一次在檢查中,然後再次訪問名稱屬性。在這裏使用if-let語法的其他答案實際上是你應該標記的那個,因爲這個轉換隻能做一次,再加上你的子類的強類型變量,所以不需要進一步轉換。 – MarqueIV

+0

我完全同意你的看法!我不喜歡我的代碼示例,也喜歡V.Khambir的代碼示例。這就是爲什麼我寫了第一句話。但是,我想指出Marmelador的代碼問題。 – Yannick

6

您應該創建所需類型的新變量並將參數放入此變量中。

func fight(attacker1: Being, attacker2: Being) -> String { 
    if let att1 = attacker1 as? Person { 
     let name1 = att1.name 
    } else { 
     print("Its not a person") 
    } 

這樣,如果attacker1是人,你只是保存該數值到ATT1不變,以後你可以用這個常量作爲類型的實例。

0

由於存在是一個基類,所以它將無法訪問任何子類屬性。所以首先,你必須檢查攻擊者1和攻擊者2的類型。例如:如果攻擊者1的類型是Person,那麼你可以將它轉換爲Person類型的實例,然後訪問person對象的屬性。 注意: - 確保首先檢查類型,然後鍵入cast,否則會崩潰。

相關問題