深入解析macOS 10.14.2中的重载与重写:面向对象编程基础概念详解

macOS 10.14.2

深入解析macOS 10.14.2中的重载与重写:面向对象编程基础概念详解

前言

重载和覆盖是面向对象语言中两个非常基本的概念。本文将讨论Obj-C中的重载和重写。

超载

在某些编程语言中,函数重载或方法重载是创建具有不同实现的同名多个函数的能力。对重载函数的调用将运行适合于调用上下文的该函数的特定实现,从而允许一个函数调用根据上下文执行不同的任务。

函数重载 - 维基百科

翻译:

在某些编程语言中,函数重载或方法重载是指创建具有相同名称但具有不同实现的多个函数的能力。调用重载函数将执行上下文函数调用,允许函数调用根据上下文执行不同的任务。

函数重载 - 维基百科

正如维基百科所说,简单来说,重载是指同一个类中具有相同函数名但参数数量不同或参数类型不同或返回值不同的函数。但由于 Obj-C 是一种消息结构语言,因此方法调用在其意义上本质上是消息传递。

@interface Computer : NSObject

- (void)run;
- (void)run:(NSString *)sth;

@end

@implementation Computer

- (void)run {
    NSLog(@"run");
}
- (void)run:(NSString *)sth {
    NSLog(@"run - %@", sth);
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Computer *cpt = [[Computer alloc] init];
        [cpt run];
        [cpt run:@"sth"];
    }
    return 0;
}

我们定义一个继承自 NSObject 的 Computer 类,并且有两个实例方法。尝试将上面的代码翻译成C++,xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-64.cpp。由于 Obj-C 是一种消息结构语言,因此 objc_msgSend 是其消息传输的地方。我们可以发现原来的方法已经变成了字符串:sel_registerName("alloc")、sel_registerName("init")、sel_registerName("run")和sel_registerName("run:")。事实上,这些字符串是 Obj-C 方法的方法名称。方法名称忽略参数名称和返回值。实例方法和类方法的区别只是消息接收对象不同。所以严格来说,Obj-C不支持方法重载,因为它不允许存在同名函数。但如果不同数量的参数也是方法重载,Obj-C 只支持不同数量参数的重载。每个参数都会在方法名后面多生成一个:,以便于区分。

int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

        Computer *cpt = ((Computer *(*)(id, SEL))(void *)objc_msgSend)((id)((Computer *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Computer"), sel_registerName("alloc")), sel_registerName("init"));
        ((void (*)(id, SEL))(void *)objc_msgSend)((id)cpt, sel_registerName("run"));
        ((void (*)(id, SEL, NSString *))(void *)objc_msgSend)((id)cpt, sel_registerName("run:"), (NSString *)&__NSConstantStringImpl__var_folders_qt_ctbfp1yd2gn7bv6y6v6qgvgm0000gn_T_main_ea7dac_mi_0);
    }
    return 0;
}

改写

在面向对象编程中,方法重写是一种语言功能,允许子类或子类提供其超类或父类之一已提供的方法的特定实现。子类中的实现通过提供与父类中的方法具有相同名称、相同参数或签名以及相同返回类型的方法来覆盖(替换)超类中的实现。执行的方法的版本将由用于调用它的对象确定。如果使用父类的对象调用方法,则执行父类中的版本,如果使用子类的对象调用方法,则执行子类中的版本。有些语言允许程序员防止方法被重写。

方法重写 - 维基百科

翻译:

在面向对象编程中,方法重写是一种语言功能,允许子类提供其父类或超类已提供的特定方法的实现。子类中的实现通过提供与超类中的方法具有相同名称、相同参数或签名以及相同返回类型的方法来覆盖(替换)超类中的实现。执行方法的版本将由调用对象确定。如果使用父类对象调用该方法,则将执行父类中的版本,但如果使用子类对象调用该方法,则将执行子类中的版本。有些语言允许程序员防止方法被重写。

方法重写 - 维基百科

@interface Mac : Computer
@end

@implementation Mac

- (void)run:(NSString *)sth {
    NSLog(@"Mac - run - %@", sth);
}

@end

与重载完全不同,重写是指在子类中重写父类的方法,并且方法名称、参数类型、参数个数、返回值类型等必须一致。 Obj-C 完全支持方法重写:

Computer *cpt = [[Computer alloc] init];
[cpt run:@"cpt_run"];
Computer *mac = [[Mac alloc] init];
[mac run:@"mac_run"];

// OUTPUT:
// run - cpt_run
// Mac - run - mac_run

参考

你可能想看:
« 上一篇
下一篇 »

相关推荐

FreeBasic:强大免费开源的64位basic编译器及应用优势

2025年05月10日

82阅读

脊柱侧弯矫正方法大盘点:运动康复、支具矫正等多种方式

2025年05月09日

87阅读

如何在winForm标题栏去掉标题文字且任务栏图标正常显示

2025年05月09日

86阅读

十一黄金周促销广告词大全,国庆购物狂欢等你来

2025年05月09日

78阅读

关闭快速编辑模式及插入模式,设置控制台指定文字颜色举例

2025年05月09日

63阅读

黄金搭档低糖高钙饮品包装及成分功效全解析,适合人群要知晓

2025年05月09日

91阅读