多态
1. 里氏替换原则 — (LSP)
子类可以替换父类的位置,并且程序的功能不受影响。
例:
Person *p1 = [Student new];
为什么?
1)父类指针迫切的需求要1个父类对象,而我们给了1个子类对象,这是完全没问题的,因为子类就是1个父类嘛。
2)因为父类中拥有的成员,子类都有,所以不会影响程序的功能。
里氏替换原则的表现形式:
当1个父类的指针指向1个子类对象的时候,这里就有里氏替换原则。
LSP的作用:
1)1个指针中不仅可以存储本类对象的地址,还可以存储子类对象的地址。
2)如果一个指针的类型是 NSObject类型的,那么这个指针可以存储任意对象的地址。
例:
NSObject *obj = [Person new];
3)如果1个数组的元素的类型是1个OC指针类型的,那么这个数组中不仅可以存储本类对象,还可以存储子类对象。
例:
Person *p1[2];
obj[0] = [Person new];
obj[1] = [Student new];
4)如果1个数组的元素是NSObject指针类型,那么就意味着任意的OC对象都可以存储到这个数组中。
例:
NSObject *obj[3];
obj[0] = [Person new];
obj[1] = [Student new];
obj[2] = @“Jack”;
5)如果1个方法的参数是1个对象,那么我们在为这个参数传值的时候,可以传递1个本类对象,也可以传递1个子类对象。对方法中的代码不会有丝毫影响。
例:
上帝杀人。
其中杀人的这个方法的参数:
可以传递Person对象,也可以传递Student对象,等等一系列子类的对象都可以。
6)当1个父类指针指向1个子类对象的时候。通过这个父类指针就只能去调用子类对象中的父类成员,子类独有的成员无法访问。
例:
Person *p1 = [Student new];
[p1 study]; // 这个是错误的!
2. 方法重写
1)子类从父类继承,子类就继承了父类的方法。
子类继承了父类的方法,就意味着子类拥有了这个功能。
但,有的时候,虽然子类也拥有父类的这个行为,但是这个行为的具体的实现和父类不同。
2)此时,就需要重写父类的这个方法。
拥有父类的行为,但是行为的具体实现和父类的实现不一样。
那么子类就自己按照自己的方式重新这个方法就可以了。
3)如何重写?
直接在类的实现中将这个方法重新实现一遍就可以了。
4)当1个父类指针指向1个子类对象的时候。
通过这个父类指针调用的方法,如果在子类对象中重写了,调用的就是子类重写的方法。
3. 多态
指的是同一个行为,对于不同的事物具有完全不同的表现形式。
例:
找三个人过来进行打招呼。
中国人
日本人
韩国人
同样的 sayHi 方法
但是实现不一样
同一个行为,具备多种形态。这样的现象就叫做多态。
4. description
1)%p 打印的是指针变量的值。
%@ 打印的是指针指向的对象。
2)如果我们使用%@打印1个对象
输出的格式:<对象所属的类名:对象的地址>
3)原理:
当我们使用%@打印1个对象的时候,NSLog函数的底层实现:
a. 调用传入的对象的 description方法。
b. 拿到这个方法的返回值,这个返回值是1个字符串。
c. 将这个字符串输出。
4)description方法是定义在NSObject类之中的。所以每1个OC对象都有这个方法。
这个方法在NSObject类中的实现是这样的:
返回的字符串格式 @“<对象所属的类名:对象的地址>”
5)什么时候需要重写description方法呢?
如果你希望使用%@打印1个对象的时候,你希望这个对象打印的个数是我们自定义的,那么就可以重写这个description方法。
例:
-(NSString *)description
{
return [NSString stringWithFormat: @“姓名:%@,年龄:%d”,_name,_age];
}
|
|