2018-05-16 16:03:09 yingBi2014 阅读数 395
  • Swift 2.1 基础实操高清视频教程

    我们通过一些代码片段学习Swift中的constant和variable、各种基本types和tuple以及Swift中重要的语言特性之一: type inference。并录制了泊学高清视频,同步搭配了泊阅文档,为开发者朋友们的学习提供了一种全新的学习视觉享受。

    8674 人正在学习 去看看 崔轶

当子类B继承自父类A时,子类不但继承父类的属性,还继承了父类的方法。可以再子类中重载和重写父类的方法。

重载:
1、不需要加override,
2、函数名和父类相同,参数可以不同,
3、可以为子类在创建时添加额外的属性,属性可以通过外部传入
4、OC 不支持函数重载,OC 的替代方式是 withXXX…

重写(覆盖):
1、需要标识override
2、方法名和参数都必须跟父类相同
3、新加的属性只能在子类内部设置

PS:final关键字可以在class、func和var前修饰,被修饰的内容不会被继承或者重新操作。可防止被重载和重写。final用法参考

重载和重写示例代码如下:

class Person: NSObject {

 var name: String // 姓名
 var age: Int  // 年龄

 // 构造函数
 init(name: String,age: Int) {
  self.name = name
  self.age = age
  super.init()
 }
}

通过重载方法为其添加属性

class Student: Person {

 var lesson: String

 /// 重载
 init(name: String, age: Int, lesson:String) {
  self.lesson = lesson
  super.init(name: name, age: age)
 }

}
 /// 重载实例化的对象
 let s1 = Student(name: "jim", age: 21, lesson: "英语")
 print(s1.lesson)

通过重写方法为其添加属性

class Student: Person {

 var lesson: String

 /// 重写
 override init(name: String, age: Int) {
  lesson = "数学"
  super.init(name: name, age: age)

 }
}

 let s = Student(name: "Joyce", age: 18)
 print(s.lesson)
2016-10-26 22:35:53 cordova 阅读数 685
  • Swift 2.1 基础实操高清视频教程

    我们通过一些代码片段学习Swift中的constant和variable、各种基本types和tuple以及Swift中重要的语言特性之一: type inference。并录制了泊学高清视频,同步搭配了泊阅文档,为开发者朋友们的学习提供了一种全新的学习视觉享受。

    8674 人正在学习 去看看 崔轶
首先,Objective-C中不完全支持重载,网上很多人要么将重载和重写搞混,要么说OC不支持重载(当然按照重载严格定义说OC不支持重载也没错),事实上OC支持参数个数不同的函数重载。


问:Objective-C和Swift中有重载吗?
答:Swift中有重载,但Objective-C中基本不支持重载。


展开:

重载、重写和隐藏三者在编程语言中的定义

重载(overload):
函数名相同,函数的参数列表不同(包括参数个数和参数类型),至于返回类型可同可不同。重载既可以发生在同一个类的不同函数之间,也可发生在父类子类的继承关系之间,其中发生在父类子类之间时要注意与重写区分开。

重写(override):发生于父类和子类之间,指的是子类不想继承使用父类的方法,通过重写同一个函数的实现实现对父类中同一个函数的覆盖,因此又叫函数覆盖。注意重写的函数必须和父类一模一样,包括函数名、参数个数和类型以及返回值,只是重写了函数的实现,这也是和重载区分开的关键。

隐藏:重载和重写区分开后,隐藏又有可能会跟前两者混在一起。当然OC中也没有隐藏,典型的C++中有,通过虚函数和父子类之间的函数重载进行区分,此处不再讨论。其中重载和重写是针对函数的,而隐藏除了函数还会针对成员变量。隐藏发生在父类和子类之间,隐藏指的是父类的同名函数或变量在子类中隐藏,其中只要函数同名就隐藏,不管参数相同与否。在子类中父类的同名函数或变量不可见,但在父类中依然存在。


Swift是基于C语言和OC语言优化后更加完善的新型语言,摆脱了C的兼容性限制,采用安全的编程模式并且增加了一些新的特性使编程更加有趣、友好,适应语言发展的趋势和期望。函数重载作为多态性的一个部分在Swift中是支持的,可能也是考虑到要弥补OC中不完全支持函数重载的这一缺陷。OC不完全支持重载,因为OC学习者应该会发现同一个类中不允许定义函数名相同且参数个数相同的两个函数,无论参数类型和返回值类型相同与否。但是说完全不支持也太绝对,因为OC中允许定义函数名相同但参数个数不同的两个函数,也就是说OC支持参数个数不同的函数重载。


例如,我们可以在一个类中定义两个参数个数不同的函数,调用时通过参数个数进行区分:

重载函数定义:
- (void)test:(int)one;
- (void)test:(int)one andTwo:(int)two;
重载函数实现:
- (void)test:(int)one {
    NSLog(@"one parameter!");
}


- (void)test:(int)one andTwo:(int)two {
    NSLog(@"two parameters!");
}
多态调用:
[self test:1];          // output:one parameter!
[self test:1 andTwo:2]; // output:two parameter!

可以看出OC可以通过参数个数实现函数重载,但是如果参数相同,无论参数和返回值类型相同与否都无法编译通过。下面的定义是无法通过xcode的编译的:
- (void)test:(int)one;
- (int)test:(float)one; // Duplicate declaration of method 'test'


2016-06-26 01:38:58 qq_24976099 阅读数 940
  • Swift 2.1 基础实操高清视频教程

    我们通过一些代码片段学习Swift中的constant和variable、各种基本types和tuple以及Swift中重要的语言特性之一: type inference。并录制了泊学高清视频,同步搭配了泊阅文档,为开发者朋友们的学习提供了一种全新的学习视觉享受。

    8674 人正在学习 去看看 崔轶

swift 中, 有函数的重载,  相对于OC , OC是没有的, 但是OC可以构造initWithXXX方法

书写原则: 

重载: 方法名相同,参数个数/参数类型不同

方法重载不仅仅局限于 init构造方法,其他的方法也同样使用


在init的构造方法中, 不需要在前面加func , 重写init需要添加关键字override . 在init方法中,需要在super.init之前完成初始化,这点与OC不同

重写是因为,系统提供的方法不能满足我们对属性的初始化的需要,在对属性初始化时,一定要用self声明属性是谁的,以防止赋值混淆

注: Xcode 7 bate 5 之后, 系统会默认 为我们调用super.init   不过, 建议熟练之前, 写上


KVC构造函数注意点: 基本数据类型不与KVC 兼容, 在KVC动态赋值的时候,找不到这个属性. 

解决办法: 在定义一个基本数据类型的同时设置默认值, 才能在KVC动态赋值的时候查找到这个属性 

例如: var age: Int = 0

KVC属性赋值的原理: 系统在运行时的时候,会动态的给 对象发送setValue forKey 这个方法,来给属性赋值

KVC属性赋值满足的2个条件: 1.对象得创建完成 2.属性完成初始化

init(dict: [String: AnyObject]){

super.init()

setValuesForKeysWithDictionary(dict)

}

同时为防止属性赋值,出现未定义的属性赋值产生崩溃,最好重写 forUndefinedKey 方法

forUndefinedKey 这个方法就是 字典里的key 找不对应的属性,就会抛出一个异常,如果我们重写这个方法,不调用父类方法,就可以不抛出异常

override func setValue(value: AnyObject?, forUndefinedKey key: String) {

} //里面什么也不要写





2016-10-26 22:37:44 cordova 阅读数 3790
  • Swift 2.1 基础实操高清视频教程

    我们通过一些代码片段学习Swift中的constant和variable、各种基本types和tuple以及Swift中重要的语言特性之一: type inference。并录制了泊学高清视频,同步搭配了泊阅文档,为开发者朋友们的学习提供了一种全新的学习视觉享受。

    8674 人正在学习 去看看 崔轶

问题:什么叫多态?

多态(Polymorphism),在面向对象语言中指的是同一个接口可以有多种不同的实现方式,OC中的多态则是不同对象对同一消息的不同响应方式,子类通过重写父类的方法来改变同一消息的实现,体现多态性。另外我们知道C++中的多态主要是通过virtual关键字(虚函数、抽象类等)来实现,具体来说指的是允许父类的指针指向子类对象,成为一个更泛化、容纳度更高的父类对象,这样父对象就可以根据实际是哪种子类对象来调用父类同一个接口的不同子类实现。

举个简单例子来展示OC的多态实现。假设有一个动物父类Animal,其下有两个子类,一个是Dog,一个是Cat,父类有一个统一接口:shout,表示动物的叫声,父类对接口有一个默认实现,子类各自有自己的接口实现,继承关系如下:

Animal父类:

// Animal.h
@interface Animal : NSObject

/**
 * 父类接口,动物叫声
 */
- (void)shout;

@end

// Animal.m
#import "Animal.h"

@implementation Animal

/**
 * 父类接口的默认实现,无语
 */
- (void)shout {
    NSLog(@"... ...");
}

@end

Dog子类:

// Dog.h
#import "Animal.h"

@interface Dog : Animal

/**
 * 重写父类接口,狗叫声
 */
- (void)shout;

@end

// Dog.m
#import "Dog.h"

@implementation Dog

/**
 * 重写父类接口,狗叫声
 */
- (void)shout {
    NSLog(@"汪汪汪,汪汪汪");
}

@end

Cat子类:

// Cat.h
#import "Animal.h"

@interface Cat : Animal

/**
 * 重写父类接口,猫叫声
 */
- (void)shout;

@end

// Cat.m
#import "Cat.h"

@implementation Cat

/**
 * 重写父类接口,猫叫声
 */
- (void)shout {
    NSLog(@"喵喵喵,喵喵喵");
}

@end

多态性测试:

    // 1. 指向Animal父类对象的Animal父类指针
    Animal *p_animal4animal = [[Animal alloc] init];
    // 2. 指向Dog子类对象的Animal父类指针
    Animal *p_animal4dog = [[Dog alloc] init];
    // 3. 指向Cat子类对象的Animal父类指针
    Animal *p_animal4cat = [[Cat alloc] init];

    // 向指向不同对象的父类指针发送相同的消息,期望得到各自不同的结果,实现多态
    [p_animal4animal shout]; // 打印结果:... ...
    [p_animal4dog shout];    // 打印结果:汪汪汪,汪汪汪
    [p_animal4cat shout];    // 打印结果:喵喵喵,喵喵喵

问题: Objective-C和Swift中有重载吗?

Swift中有重载,但Objective-C中基本不支持重载。

首先,Objective-C中不完全支持重载,网上很多人要么将重载和重写搞混,要么说OC不支持重载(当然按照重载严格定义说OC不支持重载也没错),事实上OC支持参数个数不同的函数重载。

重载、重写和隐藏三者在编程语言中的定义

重载(overload):函数名相同,函数的参数列表不同(包括参数个数和参数类型),至于返回类型可同可不同。重载发生在同一个类的不同函数之间,是横向的。重载和多态性无关。

重写(override):指的是virtual函数的重写,用来体现多态性,指的是子类不想继承使用父类的方法,通过重写同一个函数的实现实现对父类中同一个函数的覆盖,因此又叫函数覆盖。重写的函数必须和父类一模一样,包括函数名、参数个数和类型以及返回值,只是重写了函数的实现。重写发生于父类和子类之间,是纵向的。

**隐藏:**OC中也没有隐藏,典型的C++中有,通过虚函数和父子类之间的函数重写进行区分,此处不再讨论。其中重载和重写是针对函数的,而隐藏除了函数还会针对成员变量。隐藏发生在父类和子类之间,隐藏指的是父类的同名函数或变量在子类中隐藏,其中只要函数同名就隐藏,不管参数相同与否。在子类中父类的同名函数或变量不可见,但在父类中依然存在。

Swift是基于C语言和OC语言优化后更加完善的新型语言,摆脱了C的兼容性限制,采用安全的编程模式并且增加了一些新的特性使编程更加有趣、友好,适应语言发展的趋势和期望。函数重载作为多态性的一个部分在Swift中是支持的,可能也是考虑到要弥补OC中不完全支持函数重载的这一缺陷。OC不完全支持重载,因为OC学习者应该会发现同一个类中不允许定义函数名相同且参数个数相同的两个函数,无论参数类型和返回值类型相同与否。但是说完全不支持也太绝对,因为OC中允许定义函数名相同但参数个数不同的两个函数,也就是说OC支持参数个数不同的函数重载。

例如,我们可以在一个类中定义两个参数个数不同的函数,调用时通过参数个数进行区分:

重载函数定义:

- (void)test:(int)one;
- (void)test:(int)one two:(int)two;

重载函数实现:

- (void)test:(int)one {
    NSLog(@"one parameter!");
}


- (void)test:(int)one two:(int)two {
    NSLog(@"two parameters!");
}

多态调用:

[self test:1];          // output:one parameter!
[self test:1 two:2];    // output:two parameter!

可以看出OC可以通过参数个数实现函数重载,但是如果参数相同,无论参数和返回值类型相同与否都无法编译通过。下面的定义是无法通过xcode的编译的:

- (void)test:(int)one;
- (int)test:(float)one; // Duplicate declaration of method 'test'

问题: Object-C的类可以多重继承么?可以实现多个接口么?重写一个类的方式用继承好还是分类好?为什么?

Objective-C的类只支持单继承,不可以多重继承。可以利用protocol代理协议实现多个接口,通过实现多个接口完成类似C++的多重继承;在Objective-C中多态特性是通过protocol协议或者Category类别来实现的。protocol协议定义的接口函数可以被多个类实现,Category类别可以在不变动原类的情况下进行函数重写或者扩展。
一般情况用分类更好,因为用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。


问题: Cocoa中有虚基类的概念么?怎么简洁的实现?
Cocoa中没有虚基类的概念,虚基类是C++中为了解决多重继承二义性问题的,而OC中只有单继承,要实现类似C++中的多继承,可以通过protocal协议来简单实现,因为一个类可以实现多个协议,类似于Java中一个类可以实现多个接口。

2016-11-28 20:24:41 Mazy_ma 阅读数 4338
  • Swift 2.1 基础实操高清视频教程

    我们通过一些代码片段学习Swift中的constant和variable、各种基本types和tuple以及Swift中重要的语言特性之一: type inference。并录制了泊学高清视频,同步搭配了泊阅文档,为开发者朋友们的学习提供了一种全新的学习视觉享受。

    8674 人正在学习 去看看 崔轶

1、重载:

  • 函数名相同,参数名/参数类型/参数个数不同
  • 重载函数并不仅仅局限于构造函数
  • 函数重载是面相对象程序设计语言的重要标志
  • OC 不支持函数重载,OC 的替代方式是 withXXX…

2、重写:

  • 也叫覆盖,指在子类中定义一个与父类中方法同名同参数列表的方法。
  • 重写是子类的方法覆盖父类的方法,要求方法名和参数都相同
  • 因为子类会继承父类的方法,而重写就是将从父类继承过来的方法重新定义一次,重新填写方法中的代码。
  • 重写必须继承,重载不用

假设有一个Person类,用于 “name” 和 “age” 两个属性,我们分别用重写和重载方法为其添加属性

创建Person类

class Person: NSObject {

    var name: String // 姓名
    var age: Int     // 年龄

    // 构造函数
    init(name: String,age: Int) {
        self.name = name
        self.age  = age
        // 必须在 super.init() 之前 初始化对象
        super.init()
    }
}

通过重写方法为其添加 “lesson” 属性


class Student: Person {

    var lesson: String

    /// 重写
    ///
    /// - Parameters:
    ///   - name: 姓名
    ///   - age:  年龄
    override init(name: String, age: Int) {

        lesson = "Python" // 必须放在super.init()之前

        super.init(name: name, age: age)

    }
}
    /// 重写实例化的对象
    let s = Student(name: "Joyce", age: 18)
    print(s.lesson) // Python


通过重载方法为其添加 “lesson” 属性

class Student: Person {

    var lesson: String

    /// 重载
    ///
    /// - Parameters:
    ///   - name: 姓名
    ///   - age:  年龄
    ///   - lesson: 课程
    init(name: String, age: Int, lesson:String) {

        self.lesson = lesson

        super.init(name: name, age: age)
    }

}
    /// 重载实例化的对象
    let s1 = Student(name: "帅哥", age: 21, lesson: "HTML 5")
    print(s1.lesson) // HTML 5  

总结:

  • 通过重载,可以快速为方法添加新的属性,属性可以通过外部传入
  • 重写,只能在方法内部设置属性,外部无法直观看到类的参数列表

Swift属性重载

阅读数 18

重载、重写

阅读数 60

重写和重载

阅读数 5

没有更多推荐了,返回首页