OC(Objective-C)是如何实现面向对象的?

OC(Objective-C) 实现面向对象三大特性(封装、继承、多态)的方式,其核心在于 C语言 + Runtime(运行时机制)

下面我们来详细拆解OC是如何实现面向对象的。


核心思想:从 C 结构体到 OC 对象

本质上,每一个 OC 对象(如 NSObject *obj)都是一个指向结构体的指针。

  1. 封装

    • 实现方式:通过 @interface@implementation 来实现。
    • 底层原理:每个 Objective-C 类在编译后,都会对应一个 C 语言的结构体(struct)。这个结构体的第一个成员通常是 Class isa,它指向类的元数据(类对象),这是运行时机制的基石。

    示例:
    当你定义一个类 Person

    // Person.h (接口声明 - 封装)
    @interface Person : NSObject
    {
        @private
        NSString *_name; // 实例变量(Ivar)
    }
    @property (nonatomic, copy) NSString *name; // 属性(自动生成getter/setter)
    - (void)sayHello; // 方法声明
    @end
    

    底层近似结构(概念上):

    struct Person_IMPL {
        Class isa;        // 继承自NSObject,所以第一个成员是isa
        NSString *_name;  // 封装在结构体中的实例变量
    };
    
    • @public, @protected, @private 关键字用于控制实例变量的访问权限,实现了数据隐藏。
    • @property 编译器会自动生成对应的 gettersetter 方法,这些方法就是对内部实例变量进行安全访问的接口,进一步加强了封装性。
  2. 继承

    • 实现方式:通过 :父类名 的语法实现。
    • 底层原理结构体的内存布局。子类对应的结构体,其内存布局的第一个部分就是父类的结构体。这就是为什么子类可以访问父类的属性和方法,因为从内存角度看,子类对象开头就是一个完整的父类对象。

    示例:

    @interface Student : Person
    @property (nonatomic, copy) NSString *school;
    @end
    

    底层近似结构(概念上):

    struct Student_IMPL {
        struct Person_IMPL person_OBJ_Storage; // 本质上就是包含一个父类结构体
        NSString *_school;
    };
    
    • 当一个 Student 对象被创建时,它的内存中不仅包含 _school,也包含从 Person 继承来的 isa_name
    • 方法调用时,如果子类没有实现,就会沿着这个继承链(通过 isa 指针)去父类中查找。
  3. 多态

    • 实现方式:多态在 OC 中主要通过 动态类型(Dynamic Typing)动态绑定(Dynamic Binding) 来实现,这依赖于强大的 Runtime 机制。
    • 底层原理
      • 动态类型id 类型和 isa 指针。一个对象在运行时才知道其真实类型。isa 指针指向对象的类,运行时可以通过 isa 查询到对象的实际类型。
      • 动态绑定消息传递(Messaging) 机制。这是 OC 多态最核心的体现。

    示例:

    Person *p1 = [[Person alloc] init];
    Person *p2 = [[Student alloc] init]; // 多态:父类指针指向子类对象
    
    [p1 sayHello]; // 调用 Person 的 sayHello 方法
    [p2 sayHello]; // 调用 Student 的 sayHello 方法(如果Student重写了)
    

    消息传递的简化过程:
    当执行 [p2 sayHello] 时,编译器会将其转换为一个运行时函数调用 objc_msgSend(p2, @selector(sayHello))

    1. objc_msgSend 会首先找到 p2 指向的对象。
    2. 通过对象的 isa 指针找到对应的类对象 Student
    3. Student 的方法列表(method list)中查找 sayHello 方法。
    4. 如果找到,就跳转到该方法的实现(函数指针)并执行。
    5. 如果没找到,就通过类对象的 super_class 指针去父类 Person 的方法列表中查找,直到根类(NSObject)。
    • 这种运行时才决定执行哪个方法实现的机制,就是动态绑定。它允许不同的对象(Person 对象和 Student 对象)对同一消息(sayHello)做出不同的响应,这就是多态。

总结:Runtime 是面向对象的引擎

面向对象特性 OC 实现方式 底层支撑
封装 @interface / @implementation@property、访问控制符 C 结构体
继承 : 父类名 语法 结构体的内存布局(子类结构体包含父类结构体)
多态 动态类型id, isa)和 动态绑定(消息传递) Runtime 运行时机制objc_msgSend、方法列表、继承链)

关键结论:
Objective-C 的面向对象不是由编译器静态决定的,而是由 Runtime 这个动态系统在程序运行时动态创建的。类的结构、方法的查找、消息的传递都是在运行时发生的。这使得 OC 非常灵活,支持如 方法交换(Method Swizzling)动态添加方法/属性 等高级特性,这也是它与 C++ 等语言在实现面向对象上最根本的区别。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容