OC4
1.继承- - - -继承的其他特性
2.supper
3.多态
4.实例变量修饰符
5.@description
6.私有变量和私有方法
//6.@products
7.@property
8.@synthesize
1.继承:
1>继承
类似与继承父母的遗产一样,父母的东西我们也将同样拥有;
继承的语法:@interface 类名 : 需要继承的类
继承了某个类的类我们称之为子类;被继承的这个类我们称之为父类/超类
当前代码重复代码太多的时候可以利用继承来解决这个问题
只要A类继承了B类,那么A类就拥有了B类的所有属性和方法(对象方法和类方法);
其实在类名的后边加上:NSObject,就是让当前类继承NSObject类
new方法就是继承过来的
isa指针
继承的优点:
提高代码的复用性
可以让类与类之间产生关系,正式因为继承让类与类之间产生了关系所以才有了多态(也可以看作是继承和多态之间的关系)
注意:不要以为继承可以提高代码的复用性,但凡发现多个类当中有重复代码就抽取一个父类,是需要满足一定的条件我们才能使用继承:
条件:xxx 是 xxx / 某某某 is a 某某某
缺点:
耦合性太强(依赖性太强)
2>继承的其他特性
如果子类中有父类同名的方法,那么我们称之为方法重写
注意:继承中的方法调用顺序,如果自己有就调用自己的,如果自己没有就调用父类的
顺序:自己- ->父类- ->爷爷类- ->再往上- ->NSObject;
如果一直找到NSObject类还没有找到,那么就会报错;
在继承中除了方法可以重写,类方法也可以重写;
2.super用法:
只需要利用super给父类的方法发送一个消息,那么系统就会自动调用父类的方法
如果以后想在子类中调用父类的方法可以使用super
如果想在给父类方法进行扩展的同时保留父类的方法,那么可以使用super调用父类同没那个的方法
super在类方法中,一定会调用父类的类方法
super在对象中,一定调用父类的对象方法
可以利用super在任意方法中调用父类的方法
3.多态:
多态定义
事物的多种表现形式
动态类型:在编译的时候编译器只会检查当前类型对应的类中有没有需要调用的方法
在程序中的表现:父类指针指向子类对象
优点:
提高了代码的扩展性
注意点:如果父类指针指向子类对象,如果需要调用子类特有的方法,必须先强制类型转换为子类才能调用
4.实例变量修饰符
实例变量修饰符作用域:从出现的位置开始,一直到下一个修饰符出现,如果没有遇到下一个实例变量修饰符,那么就会修饰后面所有的实例变量.
1>@public
可以在其他类中方位被public修饰的成员变量;
可以在本类中访问public修饰的成员变量;
可以在子类中访问父类中public修饰的成员变量
2>@private
不可以在其他类中访问被private修饰的成员变量
可以在本类中访问被private修饰的成员变量;
不可以在子类中访问父类中被private修饰的成员变量;
3>@protected
不可以在其他类中访问被protected修饰的成员变量;
可以在本类中访问被protected修饰的成员变量;
可以在子类中访问父类中被protected修饰的成员变量;
注意:默认情况下所有的实例变量都是protected
4>@package
介于public和private之间的
如果是在其他包中访问那么就是private的
如果实在当前代码所在的包中访问就是public的
5.description
%@是用来打印对象的, 其实%@的本质是用于打印字符串
只要利用%@打印某个对象, 系统内部默认就会调用父类的description方法调用该方法, 该方法会返回一个字符串
字符串的默认格式 <类的名称: 对象的地址>
class注意c是小写, 只要给类发送class消息, 就会返回当前类的类对象
1.获取Person对应的类对象
Class c = [Person class];
2.打印Person的类对象
NSLog(@"当前对象对应的类 = %@", c);
NSLog(@"当前对象的地址 = %p", p);
可以重写description方法, 返回我们需要打印的内容
只要利用%@打印对象, 就会调用description
如果打印的是对象就会调用-号开头的description方法
访问属性有三种方式
第一种:
p->_age;
[p age];
p.age;
第二种:
self写在对象方法中就代表当前调用该方法的对象
self.age; // [self age];
self->age;
[self age];
第三种:
NSString *str = [NSString stringWithFormat:@"age = %i, name = %@, height = %f, weight = %f, tel = %@, email = %@", _age, _name, _height, _weight, _tel, _email];
return str;
建议: 在description方法中尽量不要使用self来获取成员变量,因为如果你经常在description方法中使用self, 可能已不小心就写成了 %@, self;
如果在description方法中利用%@输出self会造成死循环
self == person实例对象
return [NSString stringWithFormat:@"%@", self];
仅仅作为了解, 开发中99%的情况使用的都是-号开头的description
如果通过%@打印对象就会调用-号开头的
如果通过%@打印类对象就会调用+号开头的
无论使用什么成语变量修饰符修饰成员变量, 我们都可以在其它类中看到这个变量,只不过有得修饰符修饰的变量我们不能操作而已
6.私有变量和私有方法
如果只有方法的实现, 没有方法的声明, 那么该方法就是私有方法
在OC中没有真正的私有方法, 因为OC是消息机制
实例变量(成员变量)既可以在@interface中定义, 也可以在@implementation中定义
写在@implementation中的成员变量, 默认就是私有的成员变量, 并且和利用@private修饰的不太一样, 在@implementation中定义的成员变量在其它类中无法查看, 也无法访问
在@implementation中定义的私有变量只能在本类中访问
7.@property
1>定义:
从Xcode4.4以后apple对@property进行了一个增强, 以后只要利用一个@property就可以同时生成setter/getter方法的声明和实现
没有告诉@property要将传入的参数赋值给谁, 默认@property会将传入的属性赋值给_开头的成员变量
@porperty是一个编译器指令
在Xcode4.4之前, 可以使用@porperty来代替getter/setter方法的声明
也就是说我们只需要写上@porperty就不用写getter/setter方法的声明
编译器只要看到@property, 就知道我们要生成某一个属性的getter/setter方法的声明
setter:
作用: 用于给成员变量赋值
1.一定是对象方法
2.一定没有返回值
3.方法名称以set开头, 后面跟上需要赋值的成员变量名称, 并且去掉下划线, 然后首字母大写
4.一定有参数, 参数类型和需要赋值的成员变量一直, 参数名称就是需要赋值的成员变量名称去掉下划线
getter:
作用: 用于获取成员变量的值
1.一定是对象方法
2.一定有返回值, 返回值类型和需要获取的成员变量的类型一致
3.方法名称就是需要获取的成员变量的名称去掉下划线
4.一定没有参数
@property有一个弊端: 它只会生成最简单的getter/setter方法的声明和实现, 并不会对传入的数据进行过滤
如果想对传入的数据进行过滤, 那么我们就必须重写getter/setter方法
如果不想对传入的数据进行过滤, 仅仅是提供一个方法给外界操作成员变量, 那么就可以使用@property
如果利用@property来生成getter/setter方法, 那么我们可以不写成员变量, 系统会自动给我们生成一个_开头的成员变量
注意: @property自动帮我们生成的成员变量是一个私有的成员变量, 也就是说是在.m文件中生成的, 而不是在.h文件中生成的
如果重写了setter方法, 那么property就只会生成getter方法
如果重写了getter方法, 那么property就只会生成setter方法
如果同时重写了getter/setter方法, 那么property就不会自动帮我们生成私有的成员变量
2>property修饰符
如果给一个属性同时提供了getter/setter方法, 那么我们称这个属性为可读可写属性
如果只提供了getter方法, 那么我们称这个属性为只读属性
如果只提供了setter方法, 那么我们称这个属性为只写属性
如果既没有提供getter也没有提供setter方法, 那么我们称这个属性为私有属性
格式:
@property(属性修饰符) 数据类型 变量名称;
*/
>readwrite: 代表既生成getter方法 , 也生成setter方法
默认情况下 @property就是readwrite的
>readonly: 代表只生成getter方法不生成setter方法
>程序员之间有一个约定, 一般情况下获取BOOL类型的属性的值, 我们都会将获取的方法名称改为isXXX
例如:@property(getter=isMarried) BOOL married;
8.@synthesize
@synthesize是一个编译器指令, 它可以简化我们getter/setter方法的实现
什么是实现:
在声明后面写上大括号就代表着实现
1.在@synthesize后面告诉编译器, 需要实现哪个@property生成的声明
2. 告诉@synthesize, 需要将传入的值赋值给谁和返回谁的值给调用者
如果在@synthesize后面没有告诉系统将传入的值赋值给谁, 系统默认会赋值给和@synthesize后面写得名称相同的成员变