OC语言 - 面向对象:继承
■ 继承
OC 不允许子类和父类拥有相同名称的成员变量名,但子类可以拥有和父类相同名称的方法
OC 属于单根继承,不可以互相继承,它只能有一个父类!OC 中的根类只有一个 NSObject
继承具有传递性,子类会拥有父类除了私有实例变量以外的所有特征和行为,如果子类从父类中继承的方法不满意,可以重写该方法,但是这样会覆盖父类中的实现
继承的优缺点
1. 好处:简化代码,抽取出重复代码;建立了类和类之间的联系,保证类的完整性
2. 坏处:耦合性太强
如图所示:Person 继承了 NSObject;Student 继承了 Person
当我们在代码中书写 Student *s = [[Student alloc] init] 时,编译器就会把 Student 和它的父类全部加载进内存!每个类对象中都有一个 Superclass 指针,指向该类的父类;同样地,每个对象中有一个 isa 指针,指向该对象所属的类!注:根元类的 isa 指向自身,而它的 superClass 指向根类
■ 如何使用
代码示例:下面代码中的继承关系如是 CollegeStudent -> Student -> Person
// - Person.h
1 #import <Foundation/Foundation.h> 2 @interface Person : NSObject{ 3 NSString *_name; 4 NSString *_sex; 5 NSInteger _age; 6 } 7 8 - (void)sayHI; 9 10 - (void)setName:(NSString *)name; 11 - (NSString *)name; 12 13 - (void)setSex:(NSString *)sex; 14 - (NSString *)sex; 15 16 - (void)setAge:(NSInteger)age; 17 - (NSInteger)age; 18 19 - (id)initWithName:(NSString *)name; 20 - (id)initWithName:(NSString *)name 21 sex:(NSString *)sex; 22 - (id)initWithName:(NSString *)name 23 sex:(NSString *)sex 24 age:(NSInteger)age; 25 26 + (id)personWithName:(NSString *)name; 27 + (id)personWithName:(NSString *)name sex:(NSString *)sex; 28 29 @end
// - Person.m
1 #import "Person.h" 2 @implementation Person 3 // 重写父类方法 4 - (id)init{ 5 self = [super init]; 6 7 if (self) { 8 _name = @"Hazell"; 9 _sex = @"female"; 10 _age = 26; 11 } 12 return self; 13 } 14 15 - (void)sayHI{ 16 NSLog(@"name : %@,sex : %@ ,age : %ld",_name,_sex,_age); 17 } 18 19 - (void)setName:(NSString *)name{ 20 _name = name; 21 } 22 23 - (NSString *)name{ 24 return _name; 25 } 26 27 - (void)setSex:(NSString *)sex{ 28 _sex = sex; 29 } 30 31 - (NSString *)sex{ 32 return _sex; 33 } 34 35 - (void)setAge:(NSInteger)age{ 36 _age = age; 37 } 38 39 - (NSInteger)age{ 40 return _age; 41 } 42 43 - (id)initWithName:(NSString *)name{ 44 return [self initWithName:name sex:nil age:0]; 45 } 46 47 - (id)initWithName:(NSString *)name 48 sex:(NSString *)sex{ 49 return [self initWithName:name sex:sex age:0]; 50 } 51 52 - (id)initWithName:(NSString *)name 53 sex:(NSString *)sex 54 age:(NSInteger)age{ 55 self = [super init]; 56 if (self) { 57 _name = name; 58 _sex = sex; 59 _age = age; 60 } 61 return self; 62 } 63 64 // 便利构造器:实质上就是把初始化方法再做一层封装,是 + 方法 65 + (id)personWithName:(NSString *)name{ 66 67 Person *p =[[Person alloc] initWithName:name]; 68 return p; 69 } 70 71 + (id)personWithName:(NSString *)name sex:(NSString *)sex{ 72 73 Person *per = [[Person alloc] initWithName:name sex:sex]; 74 return per; 75 } 76 77 @end
// - Student.h
1 #import "Person.h" 2 @interface Student : Person{ 3 NSInteger _number; 4 CGFloat _score; 5 } 6 7 - (void)setNumber:(NSInteger)number; 8 - (NSInteger)number; 9 10 - (void)setScore:(CGFloat)score; 11 - (CGFloat)score; 12 13 - (id)initWithName:(NSString *)name 14 score:(CGFloat)score; 15 - (id)initWithName:(NSString *)name 16 sex:(NSString *)sex 17 score:(CGFloat)score; 18 - (id)initWithName:(NSString *)name 19 sex:(NSString *)sex 20 age:(NSInteger)age 21 number:(NSInteger)number 22 score:(CGFloat)score; 23 24 @end
// - Student.m
1 #import "Student.h" 2 @implementation Student 3 4 - (id)init{ 5 self = [super init]; 6 if (self) { 7 _number = 2010341130; 8 _score = 99.9; 9 } 10 return self; 11 } 12 13 - (void)sayHI{ 14 NSLog(@"I am a student name : %@,sex : %@,age : %ld,number : %ld,score : %.1f",_name,_sex,_age,_number,_score); 15 } 16 17 - (void)setNumber:(NSInteger)number{ 18 _number = number; 19 } 20 21 - (NSInteger)number{ 22 return _number; 23 } 24 25 - (void)setScore:(CGFloat)score{ 26 _score = score; 27 } 28 29 - (CGFloat)score{ 30 return _score; 31 } 32 33 - (id)initWithName:(NSString *)name 34 score:(CGFloat)score{ 35 return [self initWithName:name sex:nil age:0 number:0 score:score]; 36 } 37 38 - (id)initWithName:(NSString *)name 39 sex:(NSString *)sex 40 score:(CGFloat)score{ 41 return [self initWithName:name sex:sex age:0 number:0 score:score]; 42 } 43 44 - (id)initWithName:(NSString *)name 45 sex:(NSString *)sex 46 age:(NSInteger)age 47 number:(NSInteger)number 48 score:(CGFloat)score{ 49 self = [super initWithName:name sex:sex age:age]; 50 if (self) { 51 _number = number; 52 _score = score; 53 } 54 return self; 55 } 56 57 @end
// - CollegeStudent.h
1 #import "Student.h" 2 @interface CollegeStudent : Student{ 3 NSString *_major; 4 NSString *_academy; 5 } 6 7 - (void)setMajor:(NSString *)major; 8 - (NSString *)major; 9 10 - (void)setAcademy:(NSString *)academy; 11 - (NSString *)academy; 12 13 - (id)initWithName:(NSString *)name 14 sex:(NSString *)sex 15 age:(NSInteger)age 16 number:(NSInteger)number 17 score:(CGFloat)score 18 major:(NSString *)major 19 academy:(NSString *)academy; 20 - (id)initWithName:(NSString *)name 21 sex:(NSString *)sex 22 major:(NSString *)major 23 academy:(NSString *)academy; 24 - (id)initWithName:(NSString *)name 25 sex:(NSString *)sex 26 number:(NSInteger)number 27 score:(CGFloat)score 28 academy:(NSString *)academy; 29 30 @end
// - CollegeStudent.m
1 #import "CollegeStudent.h" 2 @implementation CollegeStudent 3 4 // 当从父类继承来的方法不能满足子类需求的时候,就需要重写父类方法 5 // 对象的初始化过程:首先要一级级地调用到继承树的最顶端,然后再从上往下一级级地返回对象!如果中间有一级初始化失败,那么下一层将不再初始化且返回空对象 6 - (id)init{ 7 self = [super init]; 8 if (self) { 9 _major = @"计算机科学与技术"; 10 _academy = @"研究所"; 11 } 12 return self; 13 } 14 15 - (void)sayHI{ 16 NSLog(@"I am a college student , name : %@,sex : %@,age : %ld,number : %ld,score : %.1f,major : %@,academy : %@",_name,_sex,_age,_number,_score,_major,_academy); 17 } 18 19 - (void)setMajor:(NSString *)major{ 20 _major = major; 21 } 22 23 - (NSString *)major{ 24 return _major; 25 } 26 27 - (void)setAcademy:(NSString *)academy{ 28 _academy = academy; 29 } 30 31 - (NSString *)academy{ 32 return _academy; 33 } 34 35 - (id)initWithName:(NSString *)name 36 sex:(NSString *)sex 37 age:(NSInteger)age 38 number:(NSInteger)number 39 score:(CGFloat)score 40 major:(NSString *)major 41 academy:(NSString *)academy{ 42 self = [super initWithName:name sex:sex age:age number:number score:score]; 43 if (self) { 44 _major = major; 45 _academy = academy; 46 } 47 return self; 48 } 49 50 - (id)initWithName:(NSString *)name 51 sex:(NSString *)sex 52 major:(NSString *)major 53 academy:(NSString *)academy{ 54 return [self initWithName:name sex:sex age:0 number:0 score:0 major:major academy:academy]; 55 } 56 57 - (id)initWithName:(NSString *)name 58 sex:(NSString *)sex 59 number:(NSInteger)number 60 score:(CGFloat)score 61 academy:(NSString *)academy{ 62 return [self initWithName:name sex:sex age:0 number:number score:score major:nil academy:academy]; 63 } 64 65 @end
// - main.m
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 #import "Student.h" 4 #import "CollegeStudent.h" 5 int main(int argc, const char * argv[]) { 6 @autoreleasepool { 7 8 Person *person = [[Person alloc] init]; 9 [person sayHI]; 10 Person *person01 = [Person personWithName:@"Jane"];// 使用便利构造器 11 [person01 sayHI]; 12 [person setName:@"Joson"]; 13 [person sayHI]; 14 NSLog(@"%ld",[person age]); 15 16 Student *student = [[Student alloc] init]; 17 [student sayHI];// 输出 name sex age 是有值的,因为 Student 初始化方法中调用了父类的初始化方法 18 19 // 父类赋值方法 20 [student setName:@"Jane"]; 21 [student setSex:@"female"]; 22 [student setAge:19]; 23 24 // 自身赋值方法 25 [student setNumber:2010341110]; 26 [student setScore:26]; 27 [student sayHI]; 28 29 CollegeStudent *collegestudent = [[CollegeStudent alloc] init]; 30 [collegestudent setName:@"Kardashian"]; 31 [collegestudent setAge:21]; 32 [collegestudent setSex:@"female"]; 33 [collegestudent setNumber:20153622]; 34 [collegestudent setScore:6.9]; 35 [collegestudent setMajor:@"艺术"]; 36 [collegestudent setAcademy:@"花花学院"]; 37 [collegestudent sayHI]; 38 } 39 return 0; 40 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律