-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
这次我们学习类的三大特性中的继承和多态。
继承的概念: 继承是从已有的类中派生出另一个类,这个类可以继承已有的类的属性和方法,并能够进行扩展。比如说我们新建了一个Person类,那么我们可以在这个类上派生出一个新的类Student类,Student类可以拥有Person类的全部属性和方法并能够进行扩展。
下面我们先建立一个Person类。
@interface Person : NSObject
{
int _age;
NSString *_name;
}
// name的set和get方法
- (void) setName:(NSString *)name;
- (NSString *)name;
// age的set和get方法
- (void) setAge:(int)age;
- (int) age;
// 定义一个对象方法test
- (void) eat;
@end
// 类的实现
@implementation Person
- (void) setName:(NSString *)name;
{
_name = name;
}
- (NSString *)name
{
return _name;
}
- (void) setAge:(int)age
{
_age = age;
}
- (int) age
{
return _age;
}
- (void) eat
{
NSLog(@"%@在吃饭",_name);
}
@end
类的继承关系只需要写在类的声明上,格式是在类名后面加上冒号,冒号后面写上父类的类名就可以了。
下面我们再新建一个Student类并让Student继承Person类:
@interface Student : Person
{
//这里我们定义了一个Student特有的属性_no
int _no;
}
// _no的set和get方法
- (void) setNo:(int)no;
- (int) no;
@end
@implementation Student
- (void) setNo:(int)no
{
_no = no;
}
- (int) no
{
return _no;
}
@end
上面我们定义了一个Student类并继承了Person类。可以看出我们并没有去定义Person类已有的属性,而只是定义了一个Student类特有的属性_no,那么我们怎么调用父类的方法和属性呢?下面我们开始创建main函数:
int main()
{
// 创建Student的对象并让指针s1指向这个对象
Student *s1 = [Student new];
// 设置_name的值
[s1 setName:@"张三"]; // 设置_age的值
[s1 setAge:23];
// 执行s1对象的eat方法
[s1 eat];
return 0;
}
那么继承有什么好处呢?
1. 我们可以明确地表示两个类之间的关系。
2. 子类可以继承父类的属性和方法,提高了代码的复用率。
但是继承也有一个坏处,那就是会增加程序的耦合性。也就是说当有一天我们如果删除了Person类,那么Student类也将不能再使用,这就是继承的缺点。
子类从继承父类继承过来的方法也可以进行重写,下面就是对Person类中的eat方法的重写:
@implementation Student
- (void) setNo:(int)no
{
_no = no;
}
- (int) no
{
return _no;
}
// 重写eat方法
- (void) eat
{
NSLog(@"%@今年%d岁了,他现在正在吃饭", _name, _age);
}
@end
重写eat方法后我们再在main函数中调用s1对象的eat的方法时就会调用重写后的eat方法。这时会输出:张三今年23岁了,他现在在吃饭。
继承的注意点:
1. 父类必须声明在子类的前面。
2. 子类的不能重写成员变量,因为子类中不允许有跟父类同名的成员变量。
3. 继承不是两个类有相同的属性和方法就可以确定继承关系的。比如说狗中有名字和年龄属性,还有跑和吃饭的方法,这些属性和方法人也可以拥有,但是可以让人继承狗这个类嘛,所以继承还要考虑事物之间的关系。
super的用法:
super是用来调用父类的方法的。它可以被用来调用父类中被子类重写的方法。比如说给上面的代码中重写的eat方法中再加上一句代码:
// 重写eat方法
- (void) eat
{
[super eat];
NSLog(@"%@今年%d岁了,他现在正在吃饭", _name, _age);
}
@end
上面的代码就是在子类的方法中调用了父类的方法。一般我们都是用来调用被重写的代码,因为没有被重写的代码我们的子类可以直接调用。
下面我们来学习多态。多态顾名思义就是一个对象有多种的形态,也就是说一个父类的对象既可以传入父类的对象也可以传入子类的对象。下面我们利用代码学习一下多态的用法。
#import <Foundation/Foundation.h>
// Person类的声明和实现
@interface Person : NSObject
{
int _age;
}
- (void) setAge:(int)age;
- (int) age;
- (void) eat;
@end
@implementation Person
- (void) setAge:(int)age
{
_age = age;
}
- (int) age
{
return _age;
}
- (void) eat
{
NSLog(@"吃饭了");
}
@end
// Student类的声明和实现
@interface Student : Person
{
double _score;
}
- (void)setScore:(double)score;
- (double)score;
- (void)run;
@end
@implementation Student
- (void)setScore:(double)score
{
_score = score;
}
- (double)score
{
return _score;
}
- (void)run
{
NSLog(@"跑起来了");
}
@end
int main()
{
// 多态的实现,父类的指针指向子类的对象
Person *p = [Student new];
[p eat];
Student *s = (Student *)p;
[s run];
return 0;
}
多态的特点:
1、没有继承就没有多态。
2、父类类型的变量不能直接调用子类的方法,必须要强制转化为子类类型才可以。
3、如果函数和方法形参列表中是父类的类型,则可以传入父类或子类的对象。
上面就是继承和多态的介绍。
总结:
1、继承是指一个类完全地拥有类另一个类的属性和方法。
2、继承时子类可以重写父类的方法,如果要调用父类的方法,可以用super。
3、继承不可以乱用,我们要理解两个类之间的关系,不是一个类有了另一个类的属性和方法就可以继承的。
4、继承只允许单继承,不能够同时继承多个类。
5、多态是在继承的基础上实现的。
6、多态可以在运行时根据对象的类型动态调用方法。
7、多态不可以直接调用子类的属性和方法。