2015-10-15 76 views
1

下面是一個例子項目:http://cl.ly/3N2u2i1S441M爲什麼我的超類在Swift中調用子類的方法而不是自己的方法?

我在UITableViewCell超,因爲正在啓動子當我打電話super.init()。在子類和超類的init的底部,我調用一個方法,調用styleCell,將樣式應用於它。這個方法來自它們都符合的協議,其中一個隱式地符合,因爲它是子類,它覆蓋了方法。

在超類的終結init,這種風格方法被調用,但它調用子類styleCell方法,而不是自己的。

爲什麼地球上會發生這種情況?

這是Swift的錯誤嗎?我附加了一些代碼,除了上述項目,以顯示該問題:

超類的表格單元格:

class SuperTableViewCell: UITableViewCell, Style { 
    var mysuperview: UIView! 

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
     super.init(style: style, reuseIdentifier: reuseIdentifier) 

     mysuperview = UIView() 

     doStyle() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("Must be created in code.") 
    } 

    func doStyle() { 
     print("super class") 
    } 
} 

子類的表格單元格:

class SubTableViewCell: SuperTableViewCell { 
    var mysubview: UIView! 

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
     super.init(style: style, reuseIdentifier: reuseIdentifier) 

     mysubview = UIView() 

     doStyle() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("Must be created in code.") 
    } 

    override func doStyle() { 
     super.doStyle() 

     mysubview!.backgroundColor = UIColor.greenColor() 
    } 
} 

Style類和協議:

class StyleManager: NSObject { 

} 

protocol Style { 
    func doStyle() 
} 

這會導致發生運行時錯誤,並在子類單元嘗試設置它時發生崩潰在doStyle()查看。

+0

你可以發佈代碼,MCVE嗎? –

+0

MCVE是什麼意思?我會盡快獲得代碼。 –

+0

[MCVE](http://stackoverflow.com/help/mcve) –

回答

2

想了很多,我認爲最好的例子是把它放在一個「班級」。

通過覆蓋doStyle函數,您正在有效地取代它。你仍然可以通過super.訪問它,但是我們沒有辦法從super class中調用super. 並使其指向它自己的方法。這也是有道理的,因爲super和subclass不是兩個對象。它們是一個實際上只有一個代碼源的對象,其中一個代碼在超級代碼中,另一個代碼在子代中。

所以當doStyle功能得到由super init觸發它看到替換/重寫方法。

override很擅長做它的名字,覆蓋方法。這幾乎意味着你不要使用super.method和重疊方法。

除了這一切,它也只是不好的做法。爲獨特的功能使用唯一的名稱(這是你所擁有的)。在某些方面,使用相同的名稱/協議是有意義的,因爲在每個函數中都要設置樣式。但這些不是兩個單獨的課程,都需要一種風格。您正在有效地設定基本風格和特定風格。兩件事情都需要完成。

class SuperSubIllustation { 
    // super and sub class as one for illustation 

    init() { 
     subInit() 
    } 


    func superInit() { 
     print("super init") 

     overrideDoStyle() // this calls the sub style because it's own method is overridden 

    } 

    func subInit() { // the sub init, this overrides the superInit 
     print("sub init") 

     superInit() // the super.init() 

     overrideDoStyle() // the sub style 

    } 

    func doStyle() { 
     print("super style") 
    } 

    func overrideDoStyle() { 
     print("sub style") 

     doStyle() // the super.doStyle 

    } 
} 

側面說明:

當繼承您經常產生越來越多的特定代碼。例如一系列UIButton類。儘管兩個initsuper.init被稱爲

class RoundedCornersButton : UIButton { 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     self.layer.cornerRadius = 5 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     self.layer.cornerRadius = 5 
    } 
} 


class GreenButton : RoundedCornersButton { 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     self.backgroundColor = UIColor.greenColor() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     self.backgroundColor = UIColor.greenColor() 
    } 
} 

class RedButton : RoundedCornersButton { 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     self.backgroundColor = UIColor.redColor() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     self.backgroundColor = UIColor.redColor() 
    } 
} 

,沒有衝突,因爲子類沒有同時調用它自己init和它的超類的init

相關問題