您的位置:首页 > 职场人生

黑马程序员-OC里的三大特性

2014-12-24 21:50 225 查看
[align=center]------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------[/align]
三大特性,封装,继承,多态

多态的两种形式–重载与重写。

set方法

1.作用:提供一个方法给外界设置成员变量值,可以在方法里面对参数进行相应过滤

2.命名规范:

1>方法名必须以set开头

2>set后面跟上成员变量的中称,成员变量的首字母必须大写

3>返回值一定是void

4>一定要接收一个参数,而且参数类型跟成员变量类型一致

5>形参的名称不能跟成员变量名一样

- (void)setAge:(int)newAge;

get方法

1.作用:返回对象内部的成员变量

2.命名规范:

1>肯定有返回值,返回值类型肯定与成员变量类型一致

2>方法名跟成员变量名一样(java的get方法必须以get开头)

- (int)age;

成员变量的命名规范:一定要以下划线_开头

作用:

1.让成员变量和get方法的名称区分开

2.可以跟局部变量区分开,一看到下划线开头的变量,一般都是成员变量。

通信失败

[Person test]:unrecognized selector sent to instance

给Person对象发送了一个不能识别的消息

oc是在运行过程中才会检测对象有没有实现相应的方法

对象方法

1.以减号-开头

2.只能由对象来调用

类方法

1.以加号+开头

2.只能由类(名)来调用

3.类方法中不能方问成员变量(实例)

类方法的好处和使用场合

1.不依赖于对象,执行效率高

2.能用类方法尽量用类名

3.场合:当方法内部不需要使用到成员变量时,就可以改为类方法

可以类方法和对象方法同名

实例变量age不能在类方法进行方问。

类方法调用 这样只会找类方法来用

[Person printClassName];

对象方法调用 这样只会找对象方法来用

Person *p = [Person new];

这么调用会抛出警报

[p printClassName];

当局部对象名称与成员变量重名。

//使用时报:local declaration of '_age' hides instance variable

self关键字 关于类方法与对象方法

self的用途

1.谁调用了当前方法,self就代表谁

self出现在对象方法中,self就代表对象

self出现在类方法中,self就代表类

2.在对象方法利用"self->成员变量名"访问当前对象内部的成员变量

3.[self 方法名]可以调用其他对象方法\类方法

继承的好处:

1.抽取重复代码

2.建立了类之间的关系

3.子类可以拥有父类中的所有成员变量和方法

注意点

1.基本上所有类的根类是NSObject

注意事项

1.重写:子类重新实现父类中的某个方法,覆盖父类以前的做法

2.父类必须声明在子类的前面。

3.子类不能拥有和父类相同的成员变量

4.调用某个对象方法时,优先去当前对象中寻找,如果找不到去父类中寻找。

坏处:耦合性太强

继承的使用场合。

1.当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中

2.当a类完全拥有b类中的部分属性和方法时,可以考虑让b类继承a类

a

{

int _age;

int _no;

}

b : a

{

int _weight;

}

//继承 :xx是xxx

//组合 :xxx拥有xxx

组合

A

{

int _age;

int _no

}

B

{

A *a;

int _weight;

}

super的作用

1.直接调用父类中的某一个方法

2.super处在对象方法中,那么就会调用父类的对象方法。

3.super处在类方法中,那么就会调用父类的类方法。

使用场景

子类重写父类的方法时,想保留父类的一些行为。

多态

1.没有继承就没有多态

2.代码的体现:父类类型的指针指向子类对象

3

多态的好处

用一个父类指针变量就可以指向多个子类对象

多态的局限

父类类型的变量不能用来调用子类特有的方法(子类有,父类没有的方法),必须强转为子类类型变量后,才能直接调用子类特有的方法。

解决办法,强制转换

Dog *d = (Dog *)a;

多态的灵活使用

如果参数中使用的是父类类型,可以传入父类,子类对象,调用方法时会检测对象的真实形象。

多态:父类指针指向子类对象

NSObject *n = [Animal new];

封装第一个例子 set get

/*

类名:学生 student

属性:年龄 age

行为:学习 study

*/

当属性没有@public 将无法直接通过对象来修改属性

但是可以通过对象方法来修改属性。

一般能通过方法给外界设置属性值的方法为set方法

一般能通过方法让外界获取属性值的主法为get方法

bogon:04oc whome$ touch oc13.m

bogon:04oc whome$ open oc13.m

#import<Foundation/Foundation.h>

/*
类名:学生 student
属性:年龄 age
行为:学习 study
*/
@interface Student : NSObject
{
//成员变量尽量不要用@public
int age;
}
/*
set方法
1.作用:提供一个方法给外界设置成员变量值,可以在方法里面对参数进行相应过滤
2.命名规范:
1>方法名必须以set开头
2>set后面跟上成员变量的中称,成员变量的首字母必须大写
3>返回值一定是void
4>一定要接收一个参数,而且参数类型跟成员变量类型一致
5>形参的名称不能跟成员变量名一样
*/
- (void)setAge:(int)newAge;

/*
get方法
1.作用:返回对象内部的成员变量
2.命名规范:
1>肯定有返回值,返回值类型肯定与成员变量类型一致
2》方法名跟成员变量名一样(java的get方法必须以get开头)

*/

- (int)age;

- (void)study;

@end


@implementation Student

//set方法的实现
- (void)setAge:(int)newAge
{
//对传进来的参数进行过滤
if(newAge<=0)
{
newAge = 1;
}

age = newAge;
}

//get方法的实现
- (int)age
{
return age;
}

- (void)study
{
NSLog(@"%d岁的学生在学习",age);
}
@end


int main()
{

Student *stu = [Student new];

//不建议使用下面这种方法直接改属性值。
//stu->age = 10;
//因为像下面这种不规范的赋值是无法在类接收属性值时控制的
//stu->age = -10
//推荐下面这种封装方法
[stu setAge:0];
[stu study];
[stu setAge:10];
[stu study];
//get方法
int age = [stu age];
NSLog(@"学生的年龄是%d岁",age);
return 0;
}


bogon:04oc whome$ cc oc13.m -framework Foundation

bogon:04oc whome$ ./a.out

2014-09-16 23:52:25.987 a.out[561:507] 1岁的学生在学习

2014-09-16 23:52:25.992 a.out[561:507] 10岁的学生在学习

2014-09-16 23:52:25.993 a.out[561:507] 学生的年龄是10岁

封装第二个例子 成员变量的命名规范。

bogon:~ whome$ cd Desktop/oc/04oc/

bogon:04oc whome$ open oc14.m

#import <Foundation/Foundation.h>

/*
枚举对象
*/
typedef enum{
SexMan,
SexWoman
}Sex;

/*
类名:学生 Student
属性:学号,年龄 no,age
*/
@interface Student : NSObject
{
/*
成员变量的命名规范:一定要以下划线_开头
作用:
1.让成员变量和get方法的名称区分开
2.可以跟局部变量区分开,一看到下划线开头的变量,一般都是成员变量。
*/
int _no;
Sex _sex;
}

// sex的set和get方法
- (void)setSex:(Sex)sex;
- (Sex)sex;

// no的set和get方法
- (void)setNo:(int)no;
- (int)no;

@end


//类的实现
@implementation Student
- (void)setSex:(Sex)sex
{
_sex = sex;
}
- (Sex)sex
{
return _sex;
}
- (void)setNo:(int)no
{
_no = no;
}
- (int)no
{
return _no;
}
@end


int main()
{
Student *stu = [Student new];
[stu setSex:SexMan];
[stu setNo:10];

[stu sex];
[stu no];
}


bogon:04oc whome$ cc oc14.m -framework Foundation

bogon:04oc whome$ ./a.out

封装第三个例子 设计一个成oc15.m

bogon:04oc whome$ touch oc15.m

bogon:04oc whome$ open oc15.m

#import <Foundation/Foundation.h>
/*
设计一个成绩类
属性:
c语言成绩(可读可写)
oc成绩(可读可写)
总分 (只读)
平均分 (只读)
行为:
比较c语言成绩:跟另外一个成绩对象比较c语言成绩,返回成绩差(自己-其他成绩)
比较oc成绩:跟另外一个成绩对象比较oc语言成绩,返回成绩差(自己 - 其他成绩)
比较ios成绩:跟另外一个成绩对象比较ios语言成绩,返回成绩差(自己-其他成绩)
计算总分:算出3科成绩的总分
计算平均分:算出3科成绩的平均分
*/
@interface Score : NSObject
{
int _cScore; //c语言成绩
int _ocScore;//oc成绩

int _totalScore;//总分
int _averageScore;//平均分
}

- (void)setCScore:(int)cScore;
- (int)cScore;

- (void)setOcScore:(int)ocScore;
- (int)ocScore;

- (int)totalScore;
- (int)averageScore;
@end


@implementation Score
- (void)setCScore:(int)cScore
{
_cScore = cScore;
//计算总分
_totalScore = _cScore + _ocScore;
_averageScore = _totalScore/2;
}
- (int)cScore
{
return _cScore;
}
- (void)setOcScore:(int)ocScore
{
_ocScore = ocScore;
//计算总分
_totalScore = _cScore + _ocScore;
_averageScore = _totalScore/2;
}

//监听成员变量的改变
- (int)ocScore
{
return _ocScore;
}
- (int)totalScore
{
return _totalScore;
}
- (int)averageScore
{
return _averageScore;
}
@end


int main(){
Score *s = [Score new];

[s setCScore:90];
[s setOcScore:100];

int t = [s totalScore];
int a = [s averageScore];

NSLog(@"总分:%d,平均分:%d",t,a);

return 0;
}


bogon:04oc whome$ cc oc15.m -framework Foundation

bogon:04oc whome$ ./a.out

2014-09-23 07:00:32.628 a.out[997:507] 总分:190,平均分:95

bogon:04oc whome$

封装第四个例子弱语法

弱语法就是只警告不报错的语法

类 person

调用一个不存在的方法test收集调试信息并理解

#import <Foundation/Foundation.h>
@interface Person : NSObject
- (void)test;
@end

@implementation Person
//如果没有实现就会报错,如果是没有声明,有实现的话,就只报个警报
- (void)test
{
NSLog(@"哈哈哈");
}

@end


//闪退

/*
[Person test]:unrecognized selector sent to instance
给Person对象发送了一个不能识别的消息
terminate called throwing an exception
程序被终止了
*/
int main()
{
Person *p = [Person new];
//oc是在运行过程中才会检测对象有没有实现相应的方法
[p test];
return 0;
}


bogon:04oc whome$ cc oc16.m -framework Foundation

bogon:04oc whome$ ./a.out

2014-09-23 07:59:04.282 a.out[1104:507] 哈哈哈

oc17.m:13:8: warning: 'Person' may not respond to 'test'

[p test];

~ ^

1 warning generated.

Undefined symbols for architecture x86_64:

"_OBJC_CLASS_$_NSObject", referenced from:

_OBJC_CLASS_$_Person in oc17-6479b2.o

"_OBJC_METACLASS_$_NSObject", referenced from:

_OBJC_METACLASS_$_Person in oc17-6479b2.o

"__objc_empty_cache", referenced from:

_OBJC_METACLASS_$_Person in oc17-6479b2.o

_OBJC_CLASS_$_Person in oc17-6479b2.o

"_objc_msgSend", referenced from:

_main in oc17-6479b2.o

ld: symbol(s) not found for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see invocation)

bogon:04oc whome$ cc oc17.m -framework Foundation

oc17.m:13:8: warning: 'Person' may not respond to 'test'

[p test];

~ ^

1 warning generated.

bogon:04oc whome$ ./a.out

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Person test]: unrecognized selector sent to instance 0x7fbaab502640'

*** First throw call stack:

(

0 CoreFoundation 0x00007fff8e5db25c __exceptionPreprocess + 172

1 libobjc.A.dylib 0x00007fff8bffbe75 objc_exception_throw + 43

2 CoreFoundation 0x00007fff8e5de12d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205

3 CoreFoundation 0x00007fff8e539272 ___forwarding___ + 1010

4 CoreFoundation 0x00007fff8e538df8 _CF_forwarding_prep_0 + 120

5 a.out 0x0000000102772f64 main + 68

6 libdyld.dylib 0x00007fff939ec5fd start + 1

7 ??? 0x0000000000000001 0x0 + 1

)

libc++abi.dylib: terminating with uncaught exception of type NSException

Abort trap: 6

错误总结

[Person test]:unrecognized selector sent to instance

给Person对象发送了一个不能识别的消息

terminate called throwing an exception

程序被终止了

封装第五个例子类方法

类 person

类行为,类方法和对象方法比较

//类方法 比对象方法效率高

#import <Foundation/Foundation.h>
/*
对象方法
1.以减号-开头
2.只能由对象来调用

类方法
1.以加号+开头
2.只能由类(名)来调用
3.类方法中不能方问成员变量(实例)

类方法的好处和使用场合
1.不依赖于对象,执行效率高
2.能用类方法尽量用类名
3.场合:当方法内部不需要使用到成员变量时,就可以改为类方法
可以类方法和对象方法同名
*/
@interface Person : NSObject
{
int age;
}
+ (void)printClassName;

- (void)test;
+ (void)test;

@end


@implementation Person
+ (void)printClassName
{
//error instance variable 'age' accessed in class method
//实例变量age不能在类方法进行方问。
// NSLog(@"这个类叫做Person %d",age);
NSLog(@"这个类叫做Person");
}

- (void)test
{
NSLog(@"调用了test对象方法 %d",age);
}
+ (void)test
{
NSLog(@"调用了test类方法");
}
@end


int main()
{

//类方法调用 这样只会找类方法来用
[Person printClassName];
//对象方法调用 这样只会找对象方法来用
Person *p = [Person new];
//这么调用会抛出警报
//[p printClassName];
s
[Person test];
[p test];
return 0;
}


bogon:04oc whome$ cc oc17.m -framework Foundation

bogon:04oc whome$ ./a.out

2014-10-06 07:26:55.549 a.out[653:507] 这个类叫做Person

2014-10-06 07:26:55.552 a.out[653:507] 调用了test类方法

2014-10-06 07:26:55.553 a.out[653:507] 调用了test对象方法 0

封装第六个例子类方法练习

类计算器

类行为 求和,求平均值

bogon:04oc whome$ touch oc18.m

bogon:04oc whome$ open oc18.m

//类方法练习,计算器
#import <Foundation/Foundation.h>
/*
设计一个计算器类
求和
求平均值
*/
@interface JiSusnQi : NSObject
+ (int)sumOfNum1:(int)num1 andNum2:(int)num2;
+ (int)averageOfNum1:(int)num1 andNum2:(int)num2;

@end


@implementation JiSusnQi
+ (int)sumOfNum1:(int)num1 andNum2:(int)num2
{
return num1+num2;
}
+ (int)averageOfNum1:(int)num1 andNum2:(int)num2
{
int sum  = [JiSusnQi sumOfNum1:num1 andNum2:num2];

return sum/2;
}

@end


int main(){
int a = [JiSusnQi averageOfNum1:10 andNum2:12];
NSLog(@"a=%d",a);
return 0;
}


bogon:04oc whome$ cc oc18.m -framework Foundation

bogon:04oc whome$ ./a.out

2014-10-06 07:45:54.458 a.out[684:507] a=11

类方法注意事项,类方法不能自己调用自己,会进入死循环。

封装第七个例子self关键字 关于成员变量

bogon:04oc whome$ touch oc19.m

bogon:04oc whome$ open oc19.m

//self关键字 self是个指针
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
int _age;
}

- (void)setAge : (int)age;
- (int)age;
- (void)test;
@end


@implementation Person
- (void)setAge : (int)age{
//_age = age;
self->_age = age;
}
- (int)age{

return self->_age;
//return _age;
}

- (void)test{
//访问成员变量的方法
int age1 = _age;
//当局部对象名称与成员变量重名。
//使用时报:local declaration of '_age' hides instance variable
//[-Wshadow-ivar]
int _age = 20;
//NSLog(@"age:%d", _age);

NSLog(@"age:%d",age1);

//self的使用
//self:指向了对象调用者,代表着当期对象
NSLog(@"self->age:%d",self->_age);
}

@end


int main()
{
Person *p = [Person new];
[p setAge:10];
[p test];
return 0;
}


bogon:04oc whome$ cc oc19.m -framework Foundation

bogon:04oc whome$ ./a.out

2014-10-06 21:42:00.426 a.out[467:507] age:10

2014-10-06 21:42:00.430 a.out[467:507] self->age:10

封装第八个例子self关键字 关于类方法与对象方法

类 狗dog

类行为 叫和跑 bark,run

bogon:04oc whome$ touch oc20.m

bogon:04oc whome$ open oc20.m

//self关键字 关于类方法与对象方法

/*

self的用途

1.谁调用了当前方法,self就代表谁

self出现在对象方法中,self就代表对象

self出现在类方法中,self就代表类

2.在对象方法利用"self->成员变量名"访问当前对象内部的成员变量

3.[self 方法名]可以调用其他对象方法\类方法

*/

#import <Foundation/Foundation.h>
@interface Dog :NSObject
- (void)bark;
- (void)run;
+ (void)bark;
+ (void)run;
@end


@implementation Dog
- (void)bark
{
NSLog(@"对象方法 汪汪汪");
}
- (void)run
{
[self bark];
NSLog(@"对象方法 跑起来了");
}
+ (void)bark
{
NSLog(@"类方法 汪汪汪");
}
+ (void)run
{
[self bark];
NSLog(@"类方法 跑起来了");
}
@end


int main()
{
Dog *dog = [Dog new];
[dog run];
[Dog run];
return 0;
}


bogon:04oc whome$ cc oc20.m -framework Foundation

bogon:04oc whome$ ./a.out

2014-10-06 22:34:25.917 a.out[530:507] 对象方法 汪汪汪

2014-10-06 22:34:25.922 a.out[530:507] 对象方法 跑起来了

2014-10-06 22:34:25.922 a.out[530:507] 类方法 汪汪汪

2014-10-06 22:34:25.923 a.out[530:507] 类方法 跑起来了

封装第九个例子self关键字 注意事项

类 Person 人

bogon:04oc whome$ touch oc21.m

bogon:04oc whome$ open oc21.m

//self的注意事项

/*

self的用途

1.谁调用了当前方法,self就代表谁

self出现在对象方法中,self就代表对象

self出现在类方法中,self就代表类

2.在对象方法利用"self->成员变量名"访问当前对象内部的成员变量

3.[self 方法名]可以调用其他对象方法\类方法

*/

#import <Foundation/Foundation.h>
@interface Person : NSObject
- (void)test;
+ (void)test;

- (void)test1;
+ (void)test2;

- (void)haha1;
+ (void)haha2;
@end


@implementation Person
- (void)test
{
NSLog(@"调用了-test方法");
//引发死循环
//[self test];
}

+ (void)test
{
NSLog(@"调用了+test方法");
//引发死循环
//[self test];
}
- (void)test1
{
[self test];
}
+ (void)test2
{
[self test];
}
- (void)haha1
{
NSLog(@"调用了-haha1方法");
}
+ (void)haha2
{
//这么调用是不对的,因为极sefl指向的是类不是对象
//[self haha1];
Person *p = [Person new];
[p haha1];
}
+ (void)haha3
{
[self haha2];
}
@end


int main(){
Person *p = [Person new];
[p test];
[Person test];

[p test1];

[Person test2];
[p haha1];
[Person haha2];
[Person haha3];
return 0;
}


bogon:04oc whome$ cc oc21.m -framework Foundation

bogon:04oc whome$ ./a.out

2014-10-06 23:48:10.305 a.out[584:507] 调用了-test方法

2014-10-06 23:48:10.308 a.out[584:507] 调用了+test方法

2014-10-06 23:48:10.308 a.out[584:507] 调用了-test方法

2014-10-06 23:48:10.309 a.out[584:507] 调用了+test方法

2014-10-06 23:48:10.310 a.out[584:507] 调用了-haha1方法

2014-10-06 23:48:10.311 a.out[584:507] 调用了-haha1方法

2014-10-06 23:48od0.315 a.out[584:507] 调用了-haha1方法

封装第十个例子 继承

类b继承类a

基类 动物类

猫,狗类 继承动物类

bogon:04oc whome$ touch oc22.m

bogon:04oc whome$ open oc22.m

//继承

/*

继承的好处:

1.抽取重复代码

2.建立了类之间的关系

3.子类可以拥有父类中的所有成员变量和方法

注意点

1.基本上所有类的根类是NSObject

*/

#import <Foundation/Foundation.h>
@interface Animal : NSObject
{
int _age;
double _weight;
}
- (void)setAge:(int)age;
- (int)age;

- (void)setWeight:(double)weight;
- (double)weight;

@end


@implementation Animal
- (void) setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}

- (void)setWeight:(double)weight
{
_weight = weight;
}
- (double)weight
{
return _weight;
}

@end


//: Animal 继承了Animal,相当于拥有了Animal里面的所有成员变量和方法

// Animal称为Dog的父类

// Dog称为Animal的子类

@interface Dog : Animal

@end
@implementation Dog

@end
@interface Cat : Animal

@end


@implementation Cat

@end


int main(){
Dog *d = [Dog new];
Cat *c = [Cat new];
[d setAge:10];
NSLog(@"dog age=%d",[d age]);
[c setAge:10];
NSLog(@"cat age=%d",[c age]);

return 0;
}


bogon:04oc whome$ cc oc22.m -framework Foundation

bogon:04oc whome$ ./a.out

2014-10-07 00:41:54.872 a.out[648:507] dog age=10

2014-10-07 00:41:54.875 a.out[648:507] cat age=10

封装第十一个例子 继承的使用注意

查看NSObject.h

xcode右键->contents-developer-platforms-iphoneOS platform-developer-sdk-iphoneos6.0sdk-system-library-frameworks-Foundation.framework-Headers-NSObject.h

bogon:04oc whome$ touch oc23.m

bogon:04oc whome$ open oc23.m

//继承的使用注意

#import <Foundation/Foundation.h>

/*

注意事项

1.重写:子类重新实现父类中的某个方法,覆盖父类以前的做法

2.父类必须声明在子类的前面。

3.子类不能拥有和父类相同的成员变量

4.调用某个对象方法时,优先去当前对象中寻找,如果找不到去父类中寻找。

坏处:耦合性太强

*/

//Person
@interface Person : NSObject
{
int _age;
}
- (void)setAge:(int)age;
- (int)age;
- (void)run;

+ (void)test;
@end


@implementation Person
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}
- (void)run
{
NSLog(@"Person run");
}
+ (void)test
{
NSLog(@"Person +test");
}

@end


//Student
@interface Student : Person
{
int _no;
//不允许子类和父类拥有相同名称的成员变量
//int _age;
}
@end


@implementation Student
//重写:子类重新实现父类中的某个方法,覆盖父类以前的做法
- (void)run
{
NSLog(@"Person run");
}
+ (void)test
{
NSLog(@"Student +test");
}
+ (void)test2
{
[self test];
}
@end


int main(){

Student *s = [Student new];
//如果子类没有实现run才在父类中寻找。
[s run];
[Person test];
[Student test];
[Student test2];

return 0;
}


bogon:04oc whome$ cc oc23.m -framework Foundation

bogon:04oc whome$ ./a.out

2014-10-07 01:22:18.238 a.out[702:507] Person run

2014-10-07 01:22:18.242 a.out[702:507] Person +test

2014-10-07 01:22:18.243 a.out[702:507] Student +test

2014-10-07 01:22:18.244 a.out[702:507] Student +test

封装第十二个例子 继承的使用场合

bogon:04oc whome$ touch oc24.m

bogon:04oc whome$ open oc24.m

#import<Foundation/Foundation.h>

/*

继承的使用场合。

1.当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中

2.当a类完全拥有b类中的部分属性和方法时,可以考虑让b类继承a类

a

{

int _age;

int _no;

}

b : a

{

int _weight;

}

//继承 :xx是xxx

//组合 :xxx拥有xxx

组合

A

{

int _age;

int _no

}

B

{

A *a;

int _weight;

}

*/

@interface Score : NSObject
{
int _cScore;
int _ocScore;
}
@end

@implementation Score

@end
@interface Student : NSObject
{
//组合
Score *_score;
int _age;
}
@end


@implementation Student
@end
int main(){
return 0;
}


bogon:04oc whome$ cc oc24.m -framework Foundation

封装第十三个例子 继承 super关键字

bogon:04oc whome$ touch oc25.m

bogon:04oc whome$ open oc25.m

//继承 super关键字

#import <Foundation/Foundation.h>

/*

僵尸

跳跃僵尸,舞王僵尸,铁桶僵尸

*/

/*

super的作用

1.直接调用父类中的某一个方法

2.super处在对象方法中,那么就会调用父类的对象方法。

3.super处在类方法中,那么就会调用父类的类方法。

使用场景

子类重写父类的方法时,想保留父类的一些行为。

*/

//僵尸
@interface Zoombie : NSObject
- (void)walk;
+ (void)test;
- (void)test;
@end


@implementation Zoombie
- (void)walk
{
NSLog(@"往前挪两步");
}
+ (void)test
{
NSLog(@"zoombie +test");
}
- (void)test
{
NSLog(@"xoombie -test");
}
@end
//跳跃僵尸
@interface JumpZoombie : Zoombie

@end
@implementation JumpZoombie
- (void)walk
{
NSLog(@"往前跳两下");
//super的使用,使用父类方法,不仅可以调用对象方法,还可以调用类方法
[super walk];
}
+ (void)haha
{
[super test];
}
- (void)haha
{
[super test];
}
@end
int main ()
{
JumpZoombie *jz = [JumpZoombie new];
[jz walk];
[jz haha];
[JumpZoombie haha];
return 0;
}


bogon:04oc whome$ cc oc25.m -framework Foundation

bogon:04oc whome$ ./a.out

2014-10-07 02:50:50.673 a.out[831:507] 往前跳两下

2014-10-07 02:50:50.677 a.out[831:507] 往前挪两步

2014-10-07 02:50:50.678 a.out[831:507] xoombie -test

2014-10-07 02:50:50.689 a.out[831:507] zoombie +test

封装第十四个例子 多态

多态,多种形态

bogon:04oc whome$ touch oc26.m

bogon:04oc whome$ open oc26.m

/*

多态

1.没有继承就没有多态

2.代码的体现:父类类型的指针指向子类对象

3

多态的好处

用一个父类指针变量就可以指向多个子类对象

多态的局限

父类类型的变量不能用来调用子类特有的方法(子类有,父类没有的方法),必须强转为子类类型变量后,才能直接调用子类特有的方法。

解决办法,强制转换

Dog *d = (Dog *)a;

*/

#import <Foundation/Foundation.h>
@interface Animal : NSObject
- (void)eat;
@end

@implementation Animal
- (void)eat
{
NSLog(@"eat");
}
@end
//dog
@interface Dog : Animal @end
@implementation Dog
- (void)eat
{
NSLog(@"dog eat");
}
- (void)run
{
NSLog(@"dog run");
}
@end
//cat
@interface Cat : Animal @end
@implementation Cat
- (void)eat
{
NSLog(@"cat eat");
}
@end


//多态的灵活使用

//如果参数中使用的是父类类型,可以传入父类,子类对象,调用方法时会检测对象的真实形象。

void feed(Animal *aa)

{

[aa eat];

}

int main()
{
//多种形态
//Dog类型
Dog *d = [Dog new];
//多态:父类指针指向子类对象
NSObject *n = [Animal new];
Animal *a = [Dog new];
NSObject *an = [Dog new];

//不合理的调用
Cat *c = [Animal new];//oc是弱语法,只有警告
Dog *dd = [Cat new];

NSString *s = [Cat new];//oc是弱语法,只有警告

//调用方法时会检测对象的真实形象。
[a eat];

//灵活使用
feed(d);
feed(n);
feed(an);
feed(a);
feed(c);
feed(dd);
//编译器会发出警告,因为编译器以为a是animal类型,只有运行时才会检测它的真实形态
[a run];
//强制类型转换
Dog *ddd = (Dog *)a;
[ddd run];

return 0;
}


bogon:04oc whome$ cc oc26.m -framework Foundation

oc26.m:65:10: warning: incompatible pointer types initializing 'Cat *' with an

expression of type 'Animal *' [-Wincompatible-pointer-types]

Cat *c = [Animal new];//oc是弱语法,只有警告

^ ~~~~~~~~~~~~

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/objc/NSObject.h:59:1: note:

class method 'new' is assumed to return an instance of its receiver type

('Animal *')

+ (id)new;

^

oc26.m:66:10: warning: incompatible pointer types initializing 'Dog *' with an

expression of type 'Cat *' [-Wincompatible-pointer-types]

Dog *dd = [Cat new];

^ ~~~~~~~~~

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/objc/NSObject.h:59:1: note:

class method 'new' is assumed to return an instance of its receiver type

('Cat *')

+ (id)new;

^

oc26.m:68:15: warning: incompatible pointer types initializing 'NSString *' with

an expression of type 'Cat *' [-Wincompatible-pointer-types]

NSString *s = [Cat new];//oc是弱语法,只有警告

^ ~~~~~~~~~

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/objc/NSObject.h:59:1: note:

class method 'new' is assumed to return an instance of its receiver type

('Cat *')

+ (id)new;

^

oc26.m:75:10: warning: incompatible pointer types passing 'NSObject *' to

parameter of type 'Animal *' [-Wincompatible-pointer-types]

feed(n);

^

oc26.m:49:19: note: passing argument to parameter 'aa' here

void feed(Animal *aa)

^

oc26.m:76:10: warning: incompatible pointer types passing 'NSObject *' to

parameter of type 'Animal *' [-Wincompatible-pointer-types]

feed(an);

^~

oc26.m:49:19: note: passing argument to parameter 'aa' here

void feed(Animal *aa)

^

oc26.m:81:8: warning: 'Animal' may not respond to 'run'

[a run];

~ ^

6 warnings generated.

bogon:04oc whome$ ./a.out

2014-10-07 03:57:59.265 a.out[940:507] dog eat

2014-10-07 03:57:59.267 a.out[940:507] dog eat

2014-10-07 03:57:59.267 a.out[940:507] eat

2014-10-07 03:57:59.268 a.out[940:507] dog eat

2014-10-07 03:57:59.268 a.out[940:507] dog eat

2014-10-07 03:57:59.269 a.out[940:507] eat

2014-10-07 03:57:59.269 a.out[940:507] cat eat

2014-10-07 03:57:59.270 a.out[940:507] dog run

2014-10-07 03:57:59.270 a.out[940:507] dog run

[align=center]------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: