2017-07-03 82 views
0

我想不出一個好的標題。Swift:在初始化開關後獲取子類變量

如果我有一個switch語句,其中我從一個類初始化子類,那麼它不會讓我使用子類的任何函數或變量。這就是我的意思:

class Animal {} 

class Cat: Animal {} 

class Dog: Animal { 
    func bark() { 
    print("SWIFT DOES NOT LET ME BARK") 
    } 
} 

enum AnimalType { 
    case cat, dog 
} 

func getAnimal(type: AnimalType) -> Animal { 
    let animal: Animal 
    switch type { 
    case .cat: 
    animal = Cat() 
    case .dog: 
    animal = Dog() 
    animal.bark() // Value of type 'Animal' has no member 'bark' 
    } 
    return animal 
} 

請發送幫助,我一直在想辦法解決太久。

+0

什麼你的意思做:這是行不通的。有錯誤嗎?如果是這樣,請發佈錯誤。 –

+0

@ J.Paravicini類型'動物'的價值沒有成員'樹皮'...即使它已經被初始化爲狗。 – MysteryPancake

+0

問題是,你用「動物」類型聲明瞭動物值變量,即使你給它分配了一個「狗」變量,它仍然是動物類型。你可以將它下載到roght變量 –

回答

0

的,而不是隻使用向上轉型操作者as?

修改函數等

func getAnimal(type: AnimalType) -> Animal { 
    var animal = Animal() 
    switch type { 
    case .cat: 
     let cat = animal as? Cat 
    case .dog: 
     let dog = animal as? Dog 
     dog?.bark() 
     // Value of type 'Animal' has no member 'bark' 
    } 
    return animal 
} 
+0

這些演員永遠不會成功,因爲「Animal」實例不是「Dog」或「Cat」。 – Hamish

+0

在切換檢查動物類型而不是動物。 –

+0

嘗試運行它 - 狗永遠不會吠叫。 – Hamish

1

因爲函數'bark'的定義只在'Dog'類中,而您試圖在'Animal'中調用它。 一種選擇是製作一個界面並通過'Animal' 來實現它,或者下面是將對象投射到'Dog'的另一個選項。

(animal as! Dog).bark() // Value of type 'Animal' has no member 'bark' 
0

的函數返回一個Animal也可以返回任何亞類Animal初始化animalDog類型或Cat

func getAnimal(type: AnimalType) -> Animal { 
    switch type { 
    case .cat: 
     return Cat() 
    case .dog: 
     let dog = Dog() 
     dog.bark() 
     return dog 
    } 
} 

但使用對象的功能外,你必須用(例如)as! Dog投它:

let dog = getAnimal(type: .dog) as! Dog 
dog.bark()