今天终于复习到OC的基础语法了,其实oc这门语言就是在c语言的基础上增加了面向对象的思想和语法。c语言是门面向过程的语言,面向过程关注的是解决问题需要哪些步骤,而面向对象只需要关注解决问题需要哪些对象,效率提高了很多。而且oc里面用到指针的地方很多,初始化完毕的对象都是用指针来保存的。
面向对象中有2个非常重要的概念:类和对象。
面向对象解决问题的时候必须有对象,想要用到对象就必须创建一个对象,而创建对象必须通过类来创建。因此,面向对象解决问题应该是先考虑需要设计哪些类,再利用类创建多少个对象
1、类的设计:
类的设计,只关心3样东西:
①:事物名称(类名):人(Person)
②:属性:身高(height)、年龄(age)
③:行为(功能):跑(run)、跳(jump)
2、类的创建:分为2步,第一步类的声明(interface);第二步,类的实现(implementation)。例如下面的代码:
#import
// 1.类的声明(声明对象的属性、行为)
//
// : NSObject 目的是:让Car这个类具备创建对象的能力
@interface Car : NSObject
{// 用来声明对象属性(实例变量\成员变量,默认会初始化为0)
// @public可以让外部的指针间接访问对象内部的成员变量
@public
int wheels; // 轮胎个数
int speed; // 时速(km/h)
}
- (void)run;
// 用来实现@inteface中声明的方法
@implementation Car
// 方法的实现(说清楚方法里面有什么代码)
- (void)run
{
NSLog(@"车子跑起来了");
}
@end
main函数:
int main()
{
// 在OC中,想执行一些行为,就写上一个中括号[行为执行者 行为名称]
// 利用类来创建对象
// 执行了Car这个类的new行为来创建新对象
// 定义了一个指针变量p,p将来指向的是Car类型的对象
// [Car new]每次都会创建出一个新对象,并且会返回新对象本身(新对象的地址)
Car *p = [Car new];// 开发中初始化很少用new,都是[[car alloc] init]
Car *p2 = [Car new];//oc对象都是用指针来储存的
// 给p所指向对象的wheels属性赋值
p->wheels = 4;
p->speed = 250;
// 给p所指向对象发送一条run消息(oc对象的消息机制)
[p run];
NSLog(@"车子有%d个轮子,时速位:%dkm/h", p->wheels, p2->speed);
return 0;
}
使用注意:
1.对象方法都是以减号 -
2.对象方法的声明必须写在@interface和@end之间
对象方法的实现必须写在@implementation和@end之间
3.对象方法只能由对象来调用
4.对象方法归类/对象所有
5.成员变量/实际变量,不能在interface(声明)中初始化
对象方法和类方法:
对象方法
1> 减号 - 开头
- (void)test;
2> 只能由对象来调用
3> 对象方法中能访问当前对象的成员变量(实例变量)
类方法
1> 加号 + 开头
+ (void)printClassName;
+ (void)test;
2> 只能由类(名)来调用
3> 类方法中不能访问成员变量(实例变量)
类方法的好处和使用场合:
1> 不依赖于对象,执行效率高
2> 能用类方法,尽量用类方法
3> 场合:当方法内部不需要使用到成员变量时,就可以改为类方法
可以允许类方法和对象方法同名
类的三大特性:封装、继承、多态。
1.封装:
@public的成员可以被随意赋值,应该使用set方法和get方法来管理成员的访问。
set方法
1)作用:用来设置成员变量,可以在方法里面过滤掉一些不合理的值
2)命名规范:
方法都是以set开头,而且后面跟上成员变量名,成员变量名的首字母必须大写
形参名称不要跟成员变量同名
get方法
1)作用:返回对象内部的成员变量
2)命名规范:get方法的名称一般就跟成员变量同名
使用注意:
成员变量都以下划线 _ 开头
可以跟get方法的名称区分开
可以跟其他局部变量区分开,一看到下划线开头的变量,肯定是成员变量.
#import
@interface Student : NSObject
{
int _age;
// 只读(readonly):只允许外界访问我的no,不允许外界修改我的no
int no; // 只需要提供get方法
}
- (void)setAge:(int)newAge;
- (int)age;
@end
@implementation Student
// set方法的实现
- (void)setAge:(int)newAge
{
// 对传进来的参数进行过滤
if (newAge <= 0)
{
newAge = 1;
}
_age = newAge;
}
- (int)age // getter方法的实现
{
return _age;
}
@end
int main()
{
Student *stu = [Student new];
[stu setAge:10];
NSLog(@"学生的年龄是%d岁", [stu._age]
return 0;
}
封装的好处:
过滤不合理的值;
屏蔽内部的赋值过程;
让外界不必关注内部的细节;
2.类的继承:
需要至少创建2个类,一个父类,一个子类;子类为了获得父类中的变量和方法,采用继承。oc语言的类是单继承关系,只能有一个父类。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
@interface Dog : Animal
@end
@implementation Dog
@end
继承的好处与坏处:
不改变原来模型的基础上,拓充方法;
建立了类与类之间的联系;
抽取了公共代码;
坏处:耦合性强(就是相关联,假如父类被删除,那么子类就不能使用父类的方法)
3.多态的基本概念:
某一类事物的多种形态,OC对象具有多态性。
①多态的体现:
Person *p = [Student new];
p->age = 100; // 也可以是NSObject *p = [Student new]
[p walk];
子类对象赋值给父类指针,父类指针访问对应的属性和方法。
②多态的好处:用父类接收参数,节省代码.
③多态的局限性:不能访问子类的属性(可以考虑强制转换)。