swift中构造方法和Kvc

一、引言
构造方法是一个类创建对象最先也是必须调用的方法,在Objective-C中,开发者更习惯称这类方法为初始化方法。在Objective-C中的初始化方法与普通函数相比除了要以init抬头外并无太严格的分界,而在Swift语言体系中,构造方法与普通的方法分界十分严格,从格式写法上就有不同,普通方法函数要以func声明,构造方法统一为init命名,不需要func关键字声明,不同的构造方法采用方法重载的方式创建。
二、构造方法的复写与重载
在Objective-C中,不同的初始化方法就是不同的函数,这便不存在方法重载的概念。Swift中要创建自定义的构造方法,需要开发者对init构造方法进行重载操作。任何一个自定义的类,只要其有父类,除了可以继承下来父类已有的构造方法外,还可以复写父类的构造方法,使其适用于自身。和Objective-C类似,复写父类的构造方法时,要在其中调用父类的构造方法,重载可以理解为一种特殊的复写父类构造方法,因此在重载的构造方法中也要调用父类的构造方法。

三、创建构造方法例子

//修饰便利的构造函数方法1
    //步骤是先定义,传入参数,初始化参数,调用父类构造方法
    var name:String
      init(name:String) {
       self.name = "12"
        super.init()
    }
//修饰便利的构造函数方法2
    //重载构造方法2 使用required关键字进行修饰 使用required关键字进行修饰的构造方法子类必须继承或复写
    var name:String
     required init(name:String) {
       self.name = "12"
        super.init()
    }
//修饰便利的构造函数方法2
    //重载构造方法2 使用required关键字进行修饰 使用required关键字进行修饰的构造方法子类必须继承或复写
     convenience init(name:String) {
       self.name = "12"
        self.init(name:name) //这里是系统的构造方法,将参数传进去
    }
// 在控制器中调用
  override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let stu = Student(name: "玉佳")
        print(stu.name)
       }

、Designated构造方法与Convenience构造方法

Swift中的构造方法分为Designated构造方法与Convenience构造方法两类,Designated构造方法也被称为指定构造方法,Convenience构造方法也被称为方便构造方法。Designated构造方法不加任何修饰关键字,Convenience构造方法需要使用Convenience关键字进行修饰。可以这样理解,Convenience类型的构造方法是为了方便使用从Designated构造方法中分支出来的构造方法,官方文档中有如下描述:
1.子类Designated构造方法中必须调用父类的Designated构造方法。
2.Convenience构造方法中必须调用当前类的构造方法。
3.Convenience构造方法归根结底要调用到Designated构造方法。
官方文档的一张图可以清晰的描述上述关系:

四、构造方法的继承关系
关于子类继承父类的构造方法有这样几个特性:
1.如果子类没有复写任何父类的构造方法,则默认子类将继承所有父类的构造方法,包括Designated构造方法与Convenience构造方法。
2.如果子类复写了父类某一构造方法,则子类默认不在继承所有父类的构造方法,对于Designated类型的构造方法,子类复写了哪些,哪些才能够被使用,对于Convenienve类型的构造方法,子类复写的其调用的Designated构造方法后会被自动继承。
3.如果父类中的构造方法是required修饰的,则子类必须进行继承或复写。
曾经有朋友和我抱怨,Objective-C中的继承是一种十分不人性,它强制子类继承所有父类的方法与属性无论子类是否需要,分析上面的一些规则可以发现,Swift与Objective-C相比,在构造方法方面语法会更加严格,这样做在编程上更加安全。在Objective-C中,子类将被强制继承所有父类的初始化方法,这样开发者在使用时常常会出现疑惑,有时一个子类往往有特定的初始化方法,仅仅通过父类的初始化方法不能够正确的完成初始化,在编程时,往往需要特殊注释来提示开发者。Swift设定的这些构造方法原则可以将无关的父类构造方法剔除在外,在编程时更加严格安全,减少疑惑与不可控因素。
五、构造方法的实现原则
无论Designated类型的构造方法还是Convenience类型的构造方法,只要其有父类,最终都要实现父类的Designated构造方法。Swift语言要求,在构造方法中要完成所有成员常量或者变量的构造或赋值(optional值除外)。在对成员常量或变量进行构造赋值时,要在调用父类的初始化方法之前,这里还有一点需要注意,父类的成员属性也会被子类继承,如果要在子类复写的父类方法中对继承来的父类成员属性进行重新构造或赋值,则必须在调用父类构造方法之后,

Swift语言这种强制化得构造规则,能够保证一个类在完成构造时,其内部的所有属性都构造完成。在使用Objective-C进行开发时,很多初学者都可能会遇到这样一种情况,完成了某个类的初始化,但向类的属性进行赋值时却没有成功,因为Objective-C中并没有这样的语法,在类初始化成功后,其属性是否初始化了完全取决于开发者,Swift优化了这一设计。

综上可以了解,Swift语言虽然更加严格,却将更多本来需要开发者注意的地方交由了编译器,实际上是减轻了开发者的负担。

//重写 UIBarButtonItem 构造方法
extension UIBarButtonItem {
    convenience init(title:String,target:AnyObject?,action:Selector) {
        let button = UIButton()
        button.frame = CGRect(x: 0, y: 0, width: 50, height: 40)
        button.setTitle(title, for: .normal)
        button.setTitleColor(UIColor.black, for: .normal)
        button.addTarget(target, action: action, for: .touchUpInside)
        self.init(customView:button)
    }
}
时间: 2024-10-13 23:29:28

swift中构造方法和Kvc的相关文章

java中构造方法和this,static关键字

构造方法: 构造方法是一种特殊的方法,用于创建该类的对象,对对象的数据进行初始化 格式如下: [修饰符] 类名(形参列表){ 方法体 } 特点 A:方法名和类名相同  B:没有返回值类型,连void都不能有 C:没有返回值 D:通过new关键字比如 类名 对象名 = new 类名(); 代表调用了该类的无参构造方法 构造方法注意事项: 1.如果自己不创建构造方法,系统会自动提供一个无参构造,一般建议自己手动创建 2.如果自己创建了有参构造方法,系统将不默认创建无参构造方法 class Stude

Javascript中call方法和apply方法用法和区别

第一次在博客园上面写博客,知识因为看书的时候发现了一些有意思的知识,顺便查了一下资料,就发到博客上来了,希望对大家有点帮助. 连续几天阅读<javascript高级程序设计>这本书了,逐渐发现了以前很多自己完全没有用过甚至见过的神奇知识点.今天在阅读到有关函数的属性和方法的时候,略感高级,于是乎,查阅了不少他人的博客,在此总结一下这两个方法的以下几个方面: 1.call()和apply()的作用和用法 2.什么时候用apply(),什么时候用call() 书上提到,每个函数都包含两个非继承而来

jquery中prop()方法和attr()方法的区别

jquery1.6中新加了一个方法prop(),一直没用过它,官方解释只有一句话:获取在匹配的元素集中的第一个元素的属性值. 大家都知道有的浏览器只要写disabled,checked就可以了,而有的要写成disabled = "disabled",checked="checked",比如用attr("checked")获取checkbox的checked属性时选中的时候可以取到值,值为"checked"但没选中获取值就是un

java中equals方法和“==”的比较

equals 方法是 java.lang.Object 类的方法. 有两种用法说明: (1)对于字符串变量来说,使用“==”和“equals()”方法比较字符串时,其比较方法不同. “==”比较两个变量本身的值,即两个对象在内存中的首地址. “equals()”比较字符串中所包含的内容是否相同. 比如: String s1,s2,s3 = "abc", s4 ="abc" ; s1 = new String("abc"); s2 = new St

java中paint方法和paintComponent方法的不同

/* 1.由Component.java源代码中可以看见其中的paint()方法体是空的,在Container中重写了该方法,其子类Window等也重写了该方法 2.由JComponent.java源代码中可以看见其中的paint()方法中调用paintComponent, paintChildren, paintBorder等方法: 所以该类中的paint方法会影响子组件的绘制, 而paintComponent方法只会影响该组件本身 3.paint方法 和 paintComponent方法都是

线程中sleep方法和wait方法有什么区别?(转)

线程中sleep方法和wait方法有什么区别? 如果你没有接触过java的多线程,那么多对于这两个方法可能有点陌生,看名字好像这两个方法是差不多的,但是实际上面差别好大. 首先我们看一下官方的API Sleep(sleep有两个方法,另一个方法传递两个参数,还有一个参数也是时间,只不过是纳秒级别的,所以和这个方法几乎一样,所以这里只分析这个毫秒级别的方法) public static void sleep(long millis) throws InterruptedException 首先是个

jquery中attr方法和prop方法的区别

关于checked的属性,最重要的概念就是你要记住,它跟checked的状态值是毫无关系的,设置checked = "checked"或者checked = "true"等属性设置,和它的状态值true/false是无关的.,而这里的属性值,事实上只是和defaultChecked的状态值有关,并且只能用来设置checkbox的初始的值.checked的属性值并不会随着checkbox的的状态变化而变化,可是checkbox的状态值却会.因此,为了能更好的跨浏览器的

ExtJS中listener方法和handler方法的区别

listener方法和handler方法的区别在文档中的说明的太玄乎了,看不懂 listeners监听能够对一个click Event事件添加任意多个的事件响应处理函数 而handler处理只能够通过处理函数一次处理点击响应 Ext.create('Ext.Button', { text : 'Dynamic Handler Button', renderTo: Ext.getBody(), handler : function() { // this button will spit out

oc中的构造方法和description方法,变量的作用域,

1.构造方法的声明和实现 //声明 - (id) initWithAge:(int) age andNo: (int) no; //实现 - (id) initWithAge:(int) age andNo: (int) no { self=[super init];//调用父类的init方法初始化 //判断对象是否为空 也可以直接写if(self) 或 if(self=[super init]) if(self!=nil) { _age=age; _no=no; } return self;