Java 为什么在OOPS中定义重载方法?

Java 为什么在OOPS中定义重载方法?,java,c++,oop,Java,C++,Oop,面试官问我什么是方法重载,我给出的答案是,方法重载是在同一个类中,其中两个或多个方法具有相同的名称,但签名不同,下面是一个例子- //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; } 对于这个例子,他说为什么

面试官问我什么是方法重载,我给出的答案是,方法重载是在同一个类中,其中两个或多个方法具有相同的名称,但签名不同,下面是一个例子-

//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
。相反,我们可以有两个名称不同的方法,即
addtworumbers
addtworumbers
,这表明方法名称更详细,如果我们采用这种方法,就不需要方法重载。(对于使用方法重载的其他Java API也是如此。)


考虑到他的上述想法,他问为什么OOPS原理仍然有方法重载,为什么被如此广泛地使用?发明人引入方法重载概念的意图是什么?

我认为引入方法重载是为了避免任何混淆。由于这两种方法执行相同的操作,程序员可能很容易搜索执行相同功能的相同方法名,而不是查找执行相同功能的不同名称的方法。

这背后的主要原因是代码的清洁度。 例如,让我们以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) 
这不仅使代码复杂,而且很难记住何时调用哪个函数。当最终目标相同但使用的路径或对象可能不同时,使用重载。在本例中,我们的最终目标是打印它是整数还是字符串等

考虑到他的上述想法,他问为什么OOPS原理仍然有方法重载,为什么被如此广泛地使用?发明者引入方法重载概念的意图是什么

首先,重载与OOP无关。Bjarne Stroustrup摘自:

使用继承、运行时多态性和封装是面向对象编程最常见的定义

请注意,重载不是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++中有复数、矩阵和类APL向量。有些人喜欢范围检查数组、多维数组和字符串。至少有两个独立的应用程序需要重载逻辑运算符,如I(or)、&(and)和A(异或)。在我看来,这个列表很长,而且会随着C++用户的数量和多样性而增长。我对[4]“重载使代码变得模糊”的回答是,我的几个朋友声称,如果他们有重载,他们的代码会变得更干净,我很重视他们的观点,他们的经验经过几十年的衡量。那么,如果一个人可以用重载编写晦涩难懂的代码呢?可以用任何语言编写晦涩难懂的代码。一个特性如何被很好地使用比它如何被误用更重要

    相关部分(第78页)可在中免费预览。请仔细研究一下,以便进行更详细的讨论


    虽然这是C++发明者的设计决策,但我认为类似的合理性也适用于其他语言。p> 为什么函数重载?当动作几乎相同时,只是输入的集合不同

    在Java中,使用函数重载,我们可以支持可选参数的概念(因为Java中没有对它的直接支持)


    简单的答案是,为了降低代码复杂度,因为使用这种技术将产生多态性的OOP原理(编译时多态性也称为静态绑定)。因此,我们知道借助多态性,我们可以降低代码复杂度,因为如果您在代码中有相同的行为,只使用一个名称,这将有助于开发人员更容易地了解代码中发生了什么。否则,如果您以不同的名称命名您的同类行为(方法),则理解代码将困难得多,尤其是对于正在阅读您的代码的新开发人员。

    我向您保证,拥有重载函数并不是一件可以说是“oops”的事情。但更严肃的说,重载和面向对象编程并不需要彼此,而是完全正交的。封装、继承和运行时polymorp
    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; 
    }