/*
类名:人(Person)
属性:名字、年龄
行为:吃饭
*/
//导入Foundation框架的头文件
#import
//声明Preson类
// : NSObjet 的目的是:让Person这个类具备创建对象的能力(new方法)
@interface Person : NSObject
{
//声明类的属性(成员变量),成员变量的值默认初始化为0
@public//@public可以让成员变量被外界访问
//成员变量尽量以下划线_开头。
NSString *_name;//名字 默认初始化值为空(nil) NSString 是OC字符串
int _age; //年龄 默认初始化值为0
}
//声明方法(行为)只要是OC对象的方法,必须以减号-开头
- (void)eat;
@end //类的声明结束
//类的实现
@implementation Person
//实现方法(说清楚方法里面有什么代码)
- (void) eat
{
NSLog(@"名字叫%@,年龄为%d的人在吃饭",_name,_age);
}
@end //类的实现结束
//主函数
int main()
{
//在OC中,想执行一些行为,就写上一个中括号[行为执行者 行为名称]
//利用类创建对象
//执行了Person这个类的new行为来创建对象
Person *p = [Person new];//[Person new]每次都会创建出新的对象,并且返回对象的地址,那么就应该用一个指针变量来保存对象的地址。
//设置Person对象的属性值
p -> _name = @"张三";//这里的@代表的是OC字符串
p -> _age = 25;
//给p所指向的对象发送一条eat消息,也就是调用Person对象的eat方法。
[p eat];
return 0;
//运行结果是:名字叫张三,年龄为25的人在吃饭
}
//封装
#import
@interface Student : NSObject
{
/*
成员变量得到命名规范:一定要以下划线 _开头
作用是:
1,让成员变量和get方法的名称区分开;
2,可以跟局部变量区分开,
*/
//@public //成员变量尽量不要用@public
int _age;
}
/*set方法
1,作用:提供一个方法给外界设置成员变量值
2.命名规范:
1>,方法名必须以set开头
2>,set后面跟上成员变量的名称,成员变量的字母必须大写(setAge)
3>,返回值一定是void
4>,一定要接收一个参数,而且参数类型跟成员变量类型一致
5>,形参的名称不能跟成员变量名一样
*/
//声明set方法
- (void)setAge:(int)age;
/*
get方法
1,作用:返回对象内部的成员变量。
2,命名规范:
1>,肯定有返回值,返回值类型与成员变量类型一致
2>,方法名跟成员变量名一致
3>,不需要接收任何参数
*/
//声明get方法
- (int)age;
//声明study方法
- (void)study;
@end
@implementation Student
//实现set方法
- (void)setAge:(int)age
{
//对传进来的参数进过滤
if (age <= 0)
{
age = 1;
}
_age = age;
}
//实现get方法
- (int)age
{
return _age;
}
//实现study方法
- (void)study
{
NSLog(@"%d岁的学生在学习",_age);
}
@end
int main()
{
//创建Student类对象
Student *stu = [Student new];
//stu ->_age = 10; //成员变量加@public才可以这样做,但是尽量不要这样。
[stu setAge:25];
[stu study];
NSLog(@"学生的年龄%d",[stu age]);
return 0;
}
练习
#import
@interface Dog : NSObject
{
//定义成员变量
double _weight;
double _speed;
}
//声明成员变量的set和get方法
- (void)setWeight:(double)weight;
- (double)weight;
- (void)setSpeed:(double)speed;
- (double)speed;
//声明eat和run方法
- (void)eat;
- (void)run;
@end
@implementation Dog
//成员变量的set方法的实现
- (void)setWeight:(double)weight
{
_weight = weight;
}
//成员变量get方法的实现
- (double)weight
{
return _weight;
}
//成员变量的set方法的实现
- (void)setSpeed:(double)speed
{
_speed = speed;
}
//成员变量get方法的实现
- (double)speed
{
return _speed;
}
//实现eat方法
- (void)eat
{
NSLog(@"体重为%0.1fKg的狗在吃东西",_weight);
}
//实现run方法
- (void)run
{
NSLog(@"速度为%0.1fkm/h的狗跑起来了",_speed);
}
@end
//定义主函数
int main()
{
//创建Dog类对象
Dog *d = [Dog new];
//调用set方法
[d setWeight:20];
[d setSpeed:30];
//调用eat方法
[d eat];
//调用run方法
[d run];
return 0;
}
#import
// 尽管编译器容错能力比较,但是写代码必须规范
@interface Person : NSObject
- (void)test;
@end
@implementation Person
//- (void)test
//{
// NSLog(@"哈哈哈");
//}
@end
// 一旦运行过程中出错,就会闪退
/*
-[Person test]: unrecognized selector sent to instance 0x7fd2ea4097c0
给Person对象发送了一个不能识别的消息:test
*/
int main()
{
Person *p = [Person new];
// OC是在运行过程中才会检测对象有没有实现相应的方法
[p test];
return 0;
}
// 设计一个方法输出类名
#import
@interface Person : NSObject
{
int _age;
}
//声明类方法
+ (void)printClassName;
@end
@implementation Person
//实现类方法
+ (void)printClassName
{
NSLog(@"这个类的名字是Person");
}
@end
int main()
{
//调用类方法
[Person printClassName];
return 0;
}
3,self关键字
//self练习
#import
@interface Person : NSObject
//声明类方法
+ (void)test;
+ (void)test1;
//声明对象方法
- (void)test;
- (void)test2;
@end
@implementation Person
//实现类方法
+ (void)test
{
NSLog(@"调用了类的test方法");
// //会引发死循环
// [self test];
}
//实现对象方法
- (void)test
{
NSLog(@"调用了对象的test方法");
//会引发死循环
//[self test];
}
//实现类方法
+ (void)test1
{
//这里self代表的是类
[self test];
}
//实现对象方法
- (void)test2
{
//这里self代表的是对象
[self test];
}
@end
int main()
{
Person *p = [Person new];
//调用对象方法
[p test2];
//调用类方法
[Person test1];
return 0;
}
/*运行结果是:
2014-04-06 15:12:28.178 a.out[827:707] 调用了对象的test方法
2014-04-06 15:12:28.181 a.out[827:707] 调用了类的test方法
*/
4,继承
//继承的代码体现
#import
//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类的声明,Dog继承Animal
@interface Dog : Animal
@end
//Dog类的实现
@implementation Dog
@end
//Cat类的声明,Cat继承Animal
@interface Cat : Animal
@end
//Cat类的实现
@implementation Cat
@end
int main()
{
//创建Dog对象
Dog *d = [Dog new];
//给age赋值
[d setAge:5];
//给weight赋值
[d setWeight:30];
NSLog(@"age=%d,weight=%0.1f",[d age],[d weight]);
//创建Cat对象
Cat *c = [Cat new];
//给age赋值
[c setAge:6];
//给weight赋值
[c setWeight:10];
NSLog(@"age=%d,weight=%0.1f",[c age],[c weight]);
return 0;
}
/*运行结果是
2014-04-06 16:22:26.308 a.out[978:707] age=5,weight=30.0
2014-04-06 16:22:26.310 a.out[978:707] age=6,weight=10.0
*/
<2>继承的应用
#import
//声明Person类
@interface Person : NSObject
{
//定义成员变量
NSString *_name;
int _age;
}
//声明类方法
+ (void)test;
//声明name的set方法
- (void)setName:(NSString *)name;
//声明name的get方法
- (NSString *)name;
//声明age的set方法
- (void)setAge:(int)age;
//声明age的get方法
- (int)age;
//声明run方法
-(void)run;
@end
//实现Person类
@implementation Person
//实现类方法
+ (void)test
{
NSLog(@"我是Person类的类方法!!!");
}
//实现name的set方法
- (void)setName:(NSString *)name
{
_name = name;
}
//实现name的get方法
- (NSString *)name;
{
return _name;
}
//实现age的set方法
- (void)setAge:(int)age
{
_age = age;
}
//实现age的get方法
- (int)age;
{
return _age;
}
//实现run方法
- (void)run
{
NSLog(@"名字叫%@,年龄是%d的人在跑步",_name,_age);
}
@end
//声明Student子类并且继承了Person父类
//不允许子类和父类拥有相同名称的成员变量
@interface Student : Person
{
//定义成员变量
int _no;
}
+ (void)test1;
- (void)setNo:(int)no;
- (int)no;
@end
//实现Student类
@implementation Student
+ (void)test1
{
//调用test方法,先在本类中找,如果没有,然后再去父类中找,
[self test];
}
- (void)setNo:(int)no
{
_no = no;
}
- (int)no
{
return _no;
}
//重写父类Person的run方法
- (void)run
{
NSLog(@"学号为%d,名字叫%@,年龄为%d的学生在跑步",_no,_name,_age);
}
@end
int main()
{
//创建Student类对象
Student *s = [Student new];
//设置学号
[s setNo:20140010];
//设置名字
[s setName:@"张三"];
//设置年龄
[s setAge:23];
//调用子类重写后的run方法
[s run];
//调用类方法
[Student test1];
return 0;
}
/*运行结果是
2014-04-06 18:04:56.342 a.out[1104:707] 学号为20140010,名字叫张三,年龄为23的学生在跑步
2014-04-06 18:04:56.345 a.out[1104:707] 我是Person类的类方法!!!
*/
1> 当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中
2> 当A类完全拥有B类中的部分属性和方法时,可以考虑让B类继承A类
A
{
int _age;
int _no;
}
B : A
{
int _weight;
}
// 继承:xx 是 xxx
// 组合:xxx 拥有 xxx
2.组合
A
{
int _age;
int _no;
}
B
{
A *_a;
int _weight;
}
<4>super
的作用
#1.直接调用父类中的某个方法
#2.super处在对象方法中,那么就会调用父类的对象方法; super处在类方法中,那么就会调用父类的类方法
#3.使用场合:子类重写父类的方法时想保留父类的一些行为
5,多态<1>多态的基本概念:某一事物的多种形态;OC对象具有多态性。多态:不同对象对同一消息的不同响应.子类可以重写父类的方法。
<2>多态使用
#1.没有继承就没有多态
# 2.代码的体现:父类类型的指针指向子类对象
# 3.好处:如果函数\方法参数中使用的是父类类型,可以传入父类、子类对象
#4.局限性: 父类类型的变量不能直接调用子类特有的方法。必须强转为子类类型变量后,才能直接调用子类特有的方法。
//多态
#import
@interface Animal : NSObject
- (void)eat;
@end
@implementation Animal
- (void)eat
{
NSLog(@"Animal吃东西");
}
@end
@interface Dog : Animal
- (void)run;
@end
@implementation Dog
- (void)run
{
NSLog(@"Dog跑起来了");
}
- (void)eat
{
NSLog(@"Dog吃东西");
}
@end
int main()
{
//Dog类的多态表现,Animal父类指针指向Dog子类对象
Animal *a = [Dog new];
// 调用方法时会检测对象的真实形象
[a eat];
// 多态的局限性:父类类型的变量不能用来调用子类的方法,直接调用会有警告!
/*4-多态.m:38:8: warning: 'Animal' may not respond to 'run'
[a run];
~ ^
1 warning generated.
*/
//所以将a转换为Dog类型
Dog *d = (Dog *)a;
[d run];
return 0;
}
/*运行结果为:
2014-04-06 19:41:16.678 a.out[1301:707] Dog吃东西
2014-04-06 19:41:16.679 a.out[1301:707] Dog跑起来了
*/