A继承 的作用就是为了,节省代码。
继承 :子类会继承父类 里面所有的内容
思想 :凡是继承过来的实例变量和方法 都是自己的(是从父类遗传过来的)
继承的使用场景 : 当我们多个类有部分相同特征和行为时,我们就可以把相同的部分放到同一个类里面,让下一个类继承即可
对于方法,只要声明了方法的接口,外部都可以访问到
父类 :基类 就是没有父类的类,就是继承的上层(superclass),就叫做基类 祖宗类 OC里面 NSObject。继承的下层是子类(subclass)
B.重写父类的方法: 如果在子类里面出现和父类方法重名的方法,系统就会认为他是对该方法的重写
代码demo
#import <Foundation/Foundation.h> #import "Person.h" #import "Student.h" #import "CollegeStudent.h" int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSLog(@"Hello, World!"); Person *per = [[Person alloc]init]; // [per test];//验证出来 self NSLog(@"%@",per); Person *per2 = [[Person alloc]init]; // [per2 test]; NSLog(@"%@",per2); //测试 Student 继承于 person Student *stu = [[Student alloc]init]; [stu name]; //父类里的方法、行为子类也会继承过来 // [stu test];//这里的 test 方法就是自己的方法了 [stu test];//子类对父类的重写 CollegeStudent * col = [[CollegeStudent alloc]initWithName:@"我" gender:@"男" age:23 num:1501 score:95 academy:@"大学本科" majory:@"软件工程"]; NSLog(@"%@",[col name]); } return 0; } #import <Foundation/Foundation.h> @interface Person : NSObject { @protected NSString *_name; NSString *_gender; NSInteger _age; } -(void)setName:(NSString *)name; -(void)setGender:(NSString *)gender; -(void)setAge:(NSInteger)age; //getter -(NSString *)name; -(NSString *)gender; -(NSInteger)age; // -(id)initWithName:(NSString *)name gender:(NSString *)gender age:(NSInteger)age; -(void)test; @end #import "Person.h" @implementation Person -(void)setName:(NSString *)name{ _name = name; } -(void)setGender:(NSString *)gender{ _gender = gender; } -(void)setAge:(NSInteger)age{ _age = age; } //getter -(NSString *)name{ return _name; } -(NSString *)gender{ return _gender; } -(NSInteger)age{ return _age; } // -(id)initWithName:(NSString *)name gender:(NSString *)gender age:(NSInteger)age{ _name = name; _gender = gender; _age = age; return self; } -(void)test{ NSLog(@"我是Person"); } @end #import <Foundation/Foundation.h> #import "Person.h" @interface Student : Person { /* 继承 的作用就是为了,节省代码。 继承 :子类会继承父类 里面所有的内容 思想 :凡是继承过来的实例变量和方法 都是自己的(是从父类遗传过来的) 继承的使用场景 : 当我们多个类有部分相同特征和行为时,我们就可以把相同的部分放到同一个类里面,让下一个类继承即可 对于方法,只要声明了方法的接口,外部都可以访问到 父类 :基类 就是没有父类的类,就是继承的上层(superclass),就叫做基类 祖宗类 OC里面 NSObject。继承的下层是子类(subclass) */ NSInteger _num; CGFloat _score; } //setter getter //- (void)setName:(NSString *)name; //- (void)setGender:(NSString *)gender; //- (void)steAge:(NSInteger)age; - (void)setNum:(NSInteger)num; - (void)setScore:(CGFloat)score; - (void)test;//系统会识别为子类重写父类的方法 // //- (NSString *)name; //- (NSString *)gender; //- (NSInteger)age; - (NSInteger)num; - (CGFloat)score; // -(id)initWithName:(NSString *)name gender:(NSString *)gender age:(NSInteger)age num:(NSInteger)num score:(CGFloat)score; @end #import "Student.h" @implementation Student //- (void)setName:(NSString *)name{ // _name = name; //} //- (void)setGender:(NSString *)gender{ // _gender = gender; //} //- (void)steAge:(NSInteger)age{ // _age = age; //} - (void)setNum:(NSInteger)num{ _num = num; } - (void)setScore:(CGFloat)score{ _score = score; } - (void)test{ //重写父类的方法: 如果在子类里面出现和父类方法重名的方法,系统就会认为他是对该方法的重写 /* 重写从父类继承过来的方法: 1. 完全以子类的实现为主,父类的实现内容就被丢弃 2. 完全以父类的实现为主,没有子类的实现内容 3. 既有父类里面的实现内容,又有子类的实现内容 */ //对于 3 [super test];//这是从父类里继承 super 继承父类里对该方法的实现内容 NSLog(@"这是Student类的重写方法"); } // //- (NSString *)name{ // return _name; //} //- (NSString *)gender{ // return _gender; //} //- (NSInteger)age{ // return _age; //} - (NSInteger)num{ return _num; } - (CGFloat)score{ return _score; } // -(id)initWithName:(NSString *)name gender:(NSString *)gender age:(NSInteger)age num:(NSInteger)num score:(CGFloat)score{ _name = name; _gender = gender; _age = age; _num = num; _score = score; return self; } @end #import "Student.h" @interface CollegeStudent : Student { NSString *_academy;//学院 NSString *_major;//专业 } - (void)setAcademy:(NSString *)academy; - (void)majory:(NSString *)majory; - (NSString *)academy; - (NSString *)majory; // - (id)initWithName:(NSString *)name gender:(NSString *)gender age:(NSInteger)age num:(NSInteger)num score:(CGFloat)score academy:(NSString *)academy majory:(NSString *)majory; @end #import "CollegeStudent.h" @implementation CollegeStudent - (void)setAcademy:(NSString *)academy{ _academy = academy; } - (void)setmajory:(NSString *)majory{ _major = majory; } - (NSString *)academy{ return _academy; } - (NSString *)majory{ return _major; } - (id)initWithName:(NSString *)name gender:(NSString *)gender age:(NSInteger)age num:(NSInteger)num score:(CGFloat)score academy:(NSString *)academy majory:(NSString *)majory{ //1.继承父类的初始化方法里的实现内容 self = [super initWithName:name gender:gender age:age num:num score:score];//继承 // initWithName:name 有一个ID类型返回值 // self 在这里指代一个 类的对象 //如果在父类的方法 initWithName:name 里面没有实现 则会崩溃 此时self 里面就会是空的 // if (self != Nil) {//判断前面几个实例变量赋值成功 //2. 对 self 的判断。如果 self 不为空 说明弗父类的初始化方法已经成功 //self 不为空,意味着对象已经创建,赋值成功 ??,在对象已经存在的前提下才能为其赋值 if (self) { _academy = academy; _major= majory; } //3. 如果在 OC里面如果只声明,没有实现,就会崩溃 // _name = name; // _gender = gender; // _age = age; // _num = num; // _score = score; return self; } @end
1.在初始化方法里调用 super 需要当前类的对象去接收。 如;self = [super initWithName:name gender:gender age:age num:num score:score]; self 指代当前的对象,存储当前对象的地址
对象都是用指针去指向。
2.if (self) {//这里的判断只是一种安全处理(在这讨论了 if 究竟有没有意义,已经证明是必要的,if()是一种安全处理,如果在父类的赋值方法里,返回为 Nil 这里把if 语句注释 下面的赋值语句 就会 崩溃)
_academy = academy;
_major= majory;
}
3.注意:CollegegStudent * stu1;//这一句并没有创建对象,因为对象的 创建首先要开辟内存,然后初始化,这都是在堆中 操作,而 改代码是在栈中操作,仅仅是一个指针而已。我们通常叫 stu1 是对象,是因为他指向堆中的内存,实际上他是一个指针。有的时候,我们可以写一个临时的指针用来存放一些类的对象。
4.注意:对象的实例变量、 方法在使用前,必须保证对象的存在。
+ (id)teacherWithName:(NSString *)name
gender:(NSString *)gender
age:(NSInteger)age
salary:(NSString *)salary
hobby:(NSString *)hobby;
+ (id)teacherWithName:(NSString *)name
gender:(NSString *)gender
age:(NSInteger)age
salary:(NSString *)salary
hobby:(NSString *)hobby{
Teacher * tea = [[Teacher alloc]initWithName:name gender:gender age:age salary:salary hobby:hobby];
return tea;
}
Teacher * tea = [Teacher teacherWithName:@"张老师" gender:@"男" age:24 salary:@"一月6000¥" hobby:@"吃饭、睡觉、打豆豆"];
NSLog(@"%@ %@ %ld %@ %@",[tea name],[tea gender],[tea age],[tea salary],[tea hobby]);