2015-10-15 78 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

相关问题