为什么重载OOPS中定义的方法
Why overloaded methods defined in OOPS?
采访者问我什么是方法重载,我给出的答案是,方法重载在同一个类中,其中两个或多个方法具有相同的名称但不同的签名,下面的例子-
//method with two parameters
public int add(int a, int b){
return a + b;
}
//method with three parameters
public int add(int a, int b, int c){
return a + b + c;
}
对于这个例子,他说为什么我们需要两个同名的方法,即add
。相反,我们可以有两个名称不同的方法,即addTwoNumbers
和addThreeNumbers
,这表明方法名称更详细,如果我们遵循这种方法,我们就不需要方法重载。(其他使用方法重载的Java api也是如此。)
考虑到他的上述想法,他问为什么OOPS原理仍然有方法过载,为什么被如此密集地使用?发明人引入方法重载概念的意图是什么?
考虑到他的上述想法,他问为什么OOPS原理仍然有方法重载,为什么被如此密集地使用?发明人引入方法重载概念的意图是什么?
首先,重载与OOP无关。从程序设计看Bjarne Stroustrup:使用C++的原理与实践
继承、运行时多态性和封装的使用是面向对象编程最常见的定义。
请注意,重载不是OOP的关键原则之一。
现在,如果我们谈到重载,那么支持它的逻辑是使代码可读(尽管它可以被认为是基于意见的)。例如,C具有以下功能:
int abs(int j);
long int labs(long int j);
double fabs(double x);
float fabsf(float x);
但C++已经重载了abs
版本的不同类型(不过C++仍然支持C函数以实现向后兼容性)。如果编译器本身能够区分具有相同名称但不同类型的函数,即重载函数,那么就更容易、更可读,而不是为具有不同类型的相同功能发明新名称。正如@Basilevs的评论所指出的,这也被称为静态多态性。
我们可以从C++的创造者Bjarne Stroustrup的著作《C++的设计与进化》中得到他的意图。据他说,有几个人希望运营商超载,但他最初并不情愿,因为:
- 这很难实现
- 这很难教,也很难准确定义
- 使用运算符重载的代码被认为效率低下
- 它被认为使代码无法理解
然而,如果这些问题能够得到解决,那么它就可以解决一些真正的问题,许多人都希望得到支持。他最终克服了这些问题,重载成为C++的一部分。摘自:
然而,如果所有这些猜测都是错误的,重载将为C++用户解决一些真正的问题。有些人希望在C++中使用复数、矩阵和类似APL的向量。有些人想要范围检查数组、多维数组和字符串。至少有两个独立的应用程序,人们希望重载逻辑运算符,如I(或),&(和)和A(不包括或)。在我看来,这个列表很长,而且会随着c++用户群体的规模和多样性而增长。我对[4]"重载使代码变得模糊"的回答是,我的几个朋友声称,如果他们有重载,他们的代码会变得更干净。那么,如果一个人可以用重载编写晦涩的代码呢?用任何语言编写晦涩难懂的代码都是可能的。与其说一个功能被滥用,不如说它如何被很好地使用。
相关部分(第78页)可在谷歌图书中免费预览。请看一看,以便进行更详细的讨论。
虽然这是C++的发明者做出的设计决定,但我认为类似的设计也适用于其他语言。
在我看来,引入它是为了避免任何混淆。由于两种方法执行相同的操作,程序员可能很容易搜索执行相同功能的相同方法名称,而不是查找执行相同功能、具有不同名称的方法。
这背后的主要原因是代码的清洁度例如,让我们以java中的print方法为例。它是一个重载函数,因为它可以有不同的自变量,但名称相同。
System.out.print(Boolean b),System.out.print(Integer b),System.out.print(String b),System.out.print(Float b)
等等。但我们所知道的是,有一种打印方法,我们必须通过我们需要打印的任何东西。如果没有重载,那么函数的名称看起来就像
System.out.printBoolean(Boolean b),System.out.printInteger(Integer b),System.out.printString(String b),System.out.printFloat(Float b)
这不仅使代码变得复杂,而且很难记住何时调用哪个函数。当最终目标相同,但使用的路径或对象可能不同时,会使用重载。在这种情况下,我们的最终目标是打印它是整数还是字符串等。
为什么函数重载<当动作几乎相同时,只是一组输入不同>
在Java中,使用函数重载,我们可以支持可选参数的概念(因为Java中没有直接支持它)
String formatStr(String str){ //if you don't care about having a different choice than default
String defaultPrefix = "__";
return formatStr(str, defaultPrefix);
}
String formatStr(String str, String prefix){ //You are free to choose whatever prefix you want.
return prefix + str;
}
简单的答案是因为要降低代码的复杂性,因为使用这种技术将产生多态性的OOP原理(编译时多态性也称为静态绑定)。所以我们知道,借助多态性,我们可以降低代码的复杂度,因为如果你在一个名称的代码中有相同的行为,这将帮助开发人员更容易地了解代码中发生了什么。否则,如果用不同的名称命名相同类型的行为(方法),将更难理解代码,尤其是对于正在阅读代码的新开发人员来说。
重载有帮助,因为我们有相同的方法名称,但可以灵活地提供不同数量的参数。因此,程序员不需要花很大的精力来记住不同方法的多个名称。让我们举一个使用零用钱的例子。办公室里每天的零用钱是不同的。假设一个程序员写了一个代码来计算每天的零用现金支出。然后,随着成本的变化,因为在一天我们可能会有打印成本、固定成本,在另一天旅行成本也可能包括在内,那么当参数数量发生变化时,程序员可以使用相同的函数/方法名称来计算当天的零用金总额,而不是使用多个函数名称来计算一天的零用金总数。
- 在方法定义中显式指定命名空间
- 没有针对完全专用模板类的外联虚拟方法定义
- 将虚拟方法定义为私有方法时会发生什么情况?
- 单独的类声明和方法定义文件问题
- Eclipse CDT 不了解方法定义是什么
- C 方法定义具有模板
- Eclipse CDT将方法定义定义到标头文件
- 模板方法定义的问题 - 错误C2244:无法将函数定义与现有声明匹配
- 如何为 Product* getProductFromID(std::string)编写方法定义;.
- gdb 中的方法定义没有源代码
- 方法定义中的错误"passing const List<int> as this argument discards qualifiers"
- Sendmessage在方法定义内部无法正常工作
- C 公共方法定义后定义
- C++模板方法定义在类中不匹配
- 为什么通用模板方法定义与模板类专用化不匹配?
- 方法定义中的C++模板参数
- C++方法定义和变量声明
- 在继承层次结构中将方法定义为虚拟方法一次,以使多态性发挥作用
- 未为非访问器方法定义C++类属性
- 无法将一个类的方法定义为另一个类的好友