您的位置:首页 > 编程语言 > C语言/C++

OC语言-02面向对象的三大特性

2015-12-21 11:10 363 查看

01封装

#import <Foundation/Foundation.h>

@interface Student : NSObject
{
//@public  成员变量尽量不使用
int _age;  //所有的成员变量以 _ 打头 与get方法的名称和局部变量进行区别
}
- (void)setAge:(int)age;  //set方法 提供给外界设置成员变量的值,可以在实现里对参数进行相应过滤
- (int)age;   //get方法 返回对象内部成员变量的值   如有get没有set那么这个成员变量就是只读的
- (void)study;
@end

@implementation Student
- (void)setAge:(int)age  //set方法必须以set开头,加成员变量名,变量名以大写开头
{
if(age<=0 || age>100)  //利用set方法对参数的值进行必要的过滤
{
age = 1;
}
_age = age;
}

- (int)age
{
return _age;
}

- (void)study
{
NSLog(@"%d岁的学生开始学习!",_age);
}
@end

int main()
{
Student *stu = [Student new];
[stu setAge:35];
[stu study];
NSLog(@"此时成员变量_age的值是%d",[stu age]); //使用get方法来获取成员变量的值
return 0;
}


类的方法

#import <Foundation/Foundation.h>

//工具类:基本没有 {成员变量(实例变量)[是要通过实例对象来调用的]},里面的方法基本都是类方法
//对象方法 以 - 开头 只能由对象来调用 可以访问当前对象的成员变量(实例变量)
//类方法  以 + 开头 只能由类名来调用 不可以访问成员变量,因为成员变量只有创建出实例对象后才创建
//能用方法的地方就使用类方法,效率要高,不用先去创建对象 当方法内部不需要使用成员变量的时候就使用类方法

@interface Calc : NSObject
+ (int)sumOfNum1:(int)num1 andNum2:(int)num2;
+ (int)averageOfNum1:(int)num1 andNum2:(int)num2;
@end

@implementation Calc
+ (int)sumOfNum1:(int)num1 andNum2:(int)num2
{
return num1 + num2;
}
+ (int)averageOfNum1:(int)num1 andNum2:(int)num2
{
int sum = [Calc sumOfNum1:num1 andNum2:num2]; //面向对象的思想,已经有方法可以实现加法了,不在(num1+num2)
return sum / 2 ;
}
@end

int main()
{
int sum = [Calc sumOfNum1:17 andNum2:19];
int ave = [Calc averageOfNum1:19 andNum2:18];
NSLog(@"sum=%d,average=%d",sum,ave);
return 0;
}


02继承

1.重写:子类重新实现父类中的某个方法,覆盖父类以前的做法
2.注意
1> 父类必须声明在子类的前面
2> 子类不能拥有和父类相同的成员变量
3> 调用某个方法时,优先去当前类中找,如果找不到,去父类中找

2.坏处:耦合性太强 当删除了一个类,那么它的子类也无法使用

知识点:

1.每个对象里都有一个 isa指针 指向创建了它的类 低层原理是 isa指针这个成员变量是声明在NSObject中的,继承了它的子类创建的对象都有它的成员变量isa指针

2.每个类内都有一个 superclass指向了它的父类

#import <Foundation/Foundation.h>
/*
1.继承的好处:
1> 抽取重复代码
2> 建立了类之间的关系
3> 子类可以拥有父类中的所有成员变量和方法

2.注意点
1> 基本上所有类的根类是NSObject
*/

/********Animal的声明*******/
@interface Animal : NSObject
{
int _age;
double _weight;
}

- (void)setAge:(int)age;
- (int)age;

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

/********Animal的实现*******/
@implementation Animal
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}

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

/********Dog*******/
// : Animal 继承了Animal,相当于拥有了Animal里面的所有成员变量和方法
// Animal称为Dog的父类
// Dog称为Animal的子类
@interface Dog : Animal
@end

@implementation Dog
@end

/********Cat*******/
@interface Cat : Animal
@end

@implementation Cat
@end

int main()
{
Dog *d = [Dog new];

[d setAge:10];

NSLog(@"age=%d", [d age]);
return 0;
}


有些情况下继承是不合理的 学生是分数 所以要使用<组合>

#import <Foundation/Foundation.h>

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

@implementation Score
@end

@interface Student : NSObject
{
@public
Score *_score;
int _age;
}

@end

@implementation Student
@end

int main()
{
Student *stu = [Student new];
stu->_age = 20;

Score *s= [Score new];
s->_ocScore = 89;
s->_cScore = 90;

stu->_score = s;

NSLog(@"年龄是%d,oc分数是:%d",stu->_age,stu->_score->_ocScore);

return 0;
}


03多态

/*
1.没有继承就没有多态
2.代码体现:父类类型的指针指向子类对象
3.好处:如果函数/方法参数使用的是父类类型,可以传入 父类/子类对象
4.注意:父类类型的变量不能直接调用子类特有的方法,要强转为子类类型变量后才能直接调用子类特有方法
*/

#import <Foundation/Foundation.h>

// 动物类
@interface Animal : NSObject
- (void)eat;
@end

@implementation Animal
- (void)eat
{
NSLog(@"Animal--吃东西");
}
@end

// 狗类
@interface Dog : Animal
- (void)eat; // 狗类重写了父类的 eat 方法
- (void)run; // 狗类独有的 run 方法
@end

@implementation Dog
- (void)eat
{
NSLog(@"Dog--吃东西");
}
- (void)run
{
NSLog(@"Dog--跑起来");
}
@end

// 猫类
@interface Cat : Animal
- (void)eat; //猫类重写的父类的 eat 方法
@end

@implementation Cat
- (void)eat
{
NSLog(@"Cat--吃东西");
}
@end

//定义一个 喂 的函数
void feed(Animal *a) //注意传入的参数是父类指针
{
//虽然父类指针中实际是动态绑定的真实对象,但编译器还是会认为它存着父类对象,所以,如果这个方法是子类独有的,父类中不存在这个 eat 方法 ,编译器会报警告,也许找不到 eat 方法
[a eat];
}

int main()
{
Dog *d = [Dog new];
//虽接收者是父类指针,但程序会动态的绑定真实的对象,掉用对象中的方法
feed(d);
Cat *c = [Cat new];
feed(c);

Animal *a = [Dog new];
//    [a run]; //run 是狗独有的方法 编译时会报警告 在Animal中找不到 run方法

Dog *dd = (Dog *)a; // 强转
//[(Dog *)a run]; // 这样也是可以的 不用在额外声明一个指针
[dd run];

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: