Java支持方法重载的原因

网友投稿 228 2023-01-07

Java支持方法重载的原因

java为什么要支持方法重载

为什么要使用重载?而不是把一个方法名字换成不同的。

任何编程语言中都具备的一项重要特性就是名称。当你创建一个对象时,就会给此对象分配的内存空间一个名称。一个方法就是一种行为的名称。通过名称引用所各种对象,属性和方法。良好的命名可以让系统易于理解和修改。

将人类语言细微的差别映射到编程语言中会产生一个问题。通常,相同的词可以表达多种不同的含义——它们被"重载"了。特别是当含义的差别很小时,这会更加有用。

你会说"清洗衬衫"、“清洗车"和"清洗狗”。而如果硬要这么说就会显得很愚蠢:“以洗衬衫的方式洗衬衫”、“以洗车的方式洗车"和"以洗狗的方式洗狗”,因为听众根本不需要区分行为的动作。大多数人类语言都具有"冗余"性,所以即使漏掉几个词,你也能明白含义。你不需要对每个概念都使用不同的词汇——可以从上下文推断出含义。

大多数编程语言(尤其是 C)要求为每个方法(在这些语言中经常称为函数)提供一个独一无二的标识符。所以,你不能有一个 print() 函数既能打印整型,也能打印浮点型——每个函数名都必须不同。

但在 Java (C++) 中,还有一个因素也促使了必须使用方法重载:构造器。因为构造器方法名肯定与类名相同,所以一个类中只会有一个构造器名。

那么你怎么通过不同方式创建一个对象?例如,你想创建一个类,这个类的初始化方式有两种:一种是标准化方式,另一种是从文件中读取信息的方式。你需要两个构造器:无参构造器和有一个 String 类型参数的构造器,该参数传入文件名。两个构造器具有相同的名字——与类名相同。因此,方法重载是必要的,它允许方法具有相同的方法名但接收的参数不同。尽管方法重载对于构造器很重要,但也可以对任何方法很方便地进行重载。

重载构造器和方法:

class Tree {

int height;

Tree() {

System.out.println("Planting a seedling");

height = 0;

}

Tree(int initialHeight) {

height = initialHeight;

System.out.println("Creating new Tree that is " + height + " feet tall");

}

void info() {

System.out.println("Tree is " + height + " feet tall");

}

void info(String s) {

System.out.println(s + ": Tree is " + height + " feet tall");

}

}

public class Overloading {

public static void main(String[] args) {

for (int i = 0; i < 5; i++) {

Tree t = new Tree(i);

t.info();

t.info("overloaded method");

}

new Tree();

}

}

一个 Tree 对象既可以是一颗树苗,使用无参构造器,也可以是一颗在温室中已长大的树,已经有一定高度,这就需要有参构造器。

你也许想以多种方式调用 info()。比如,如果你想打印额外的消息,就可以使用 info(String) 方法。若你无话可说,就可以使用 info() 方法。用两个命名定义完全相同的概念看起来很奇怪,而使用方法重载,你就可以使用一个命名来定义一个概念。

区分重载方法

如果两个方法命名相同,Java是怎么知道你调用的是哪个呢?

有一条简单的规则:每个被重载的方法必须有独一无二的参数列表。

除了通过参数列表的不同来区分两个相同命名的方法,其他也没什么方式了。你甚至可以根据参数列表中的参数顺序来区分不同的方法,尽管这会造成代码难以维护。

重载与基本类型

基本类型可以自动从小类型转为大类型。当这与重载结合时,这会令人有点困惑:

public class PrimitiveOverloading {

void f1(char x) {

System.out.print("f1(char)");

}

void f1(byte x) {

System.out.print("f1(byte)");

}

void f1(short x) {

System.out.print("f1(short)");

}

void f1(int x) {

System.out.print("f1(int)");

}

void f1(long x) {

System.out.print("f1(long)");

}

void f1(float x) {

System.out.print("f1(float)");

}

void f1(double x) {

System.out.print("f1(double)");

}

void f2(byte x) {

System.out.print("f2(byte)");

}

void f2(short x) {

System.out.print("f2(short)");

}

void f2(int x) {

System.out.print("f2(int)");

}

void f2(long x) {

System.out.print("f2(long)");

}

void f2(float x) {

System.out.print("f2(float)");

}

void f2(double x) {

System.out.print("f2(double)");

}

void f3(short x) {

System.out.print("f3(short)");

}

void f3(int x) {

System.out.print("f3(int)");

}

void f3(long x) {PABUmPSs

System.out.print("f3(long)");

}

void f3(float x) {

System.out.print("f3(float)");

}

void f3(double x) {

System.out.print("f3(double)");

}

void f4(int x) {

System.out.print("f4(int)");

}

void f4(long x) {

System.out.print("f4(long)");

}

void f4(float x) {

System.out.print("f4(float)");

}

void f4(double x) {

System.out.print("f4(double)");

}

void f5(long x) {

System.out.print("f5(long)");

}

void f5(float x) {

System.out.print("f5(float)");

}

void f5(double x) {

System.out.print("f5(double)");

}

void f6(float x) {

System.out.print("f6(float)");

}

void f6(double x) {

System.out.print("f6(double)");

}

void f7(double x) {

System.out.print("f7(double)");

}

void testConstVal() {

System.out.print("5: ");

f1(5);f2(5);f3(5);f4(5);f5(5PABUmPSs);f6(5);f7(5);

System.out.println();

}

void testChar() {

char x = 'x';

System.out.print("char: ");

f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);

System.out.println();

}

void testByte() {

byte x = 0;

System.out.print("byte: ");

f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);

System.out.println();

}

void testShort() {

short x = 0;

System.out.print("short: ");

f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);

System.out.println();

}

void testInt() {

int x = 0;

System.out.print("int: ");

f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);

System.out.println();

}

void testLong() {

long x = 0;

System.out.print("long: ");

f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);

System.out.println();

}

void testFloat() {

float x = 0;

System.out.print("float: ");

f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);

System.out.println();

}

void testDouble() {

double x = 0;

System.out.print("double: ");

f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);

System.out.println();

}

public static void main(String[] args) {

PrimitiveOverloading p = new PrimitiveOverloading();

p.testConstVal();

p.testChar();

p.testByte();

p.testShort();

p.testInt();

p.testLong();

p.testFloat();

p.testDouble();

}

}

输出:

5: f1(int)f2(int)f3(int)f4(int)f5(long)f6(float)f7(double)

char: f1(char)f2(int)f3(int)f4(int)f5(long)f6(float)f7(double)

byte: f1(byte)f2(byte)f3(short)f4(int)f5(long)f6(float)f7(double)

short: f1(short)f2(short)f3(short)f4(int)f5(long)f6(float)f7(double)

int: f1(int)f2(int)f3(int)f4(int)f5(long)f6(float)f7(double)

long: f1(long)f2(long)f3(long)f4(long)f5(long)f6(float)f7(double)

float: f1(float)f2(float)f3(float)f4(float)f5(float)f6(float)f7(double)

double: f1(double)f2(double)f3(double)f4(double)f5(double)f6(double)f7(double)

若传入的参数类型大于方法期望接收的参数类型,你必须首先做缩窄转换,否则编译器就会报错。

返回值的重载

经常会有人困惑,“为什么只能通过类名和参数列表,不能通过方法的返回值区分方法呢?”。例如以下两个方法,它们有相同的命名和参数,但是很容易区分:

void f(){}

int f() {return 1;}

有些情况下,编译器很容易就可以从上下文准确推断出该调用哪个方法,如 int x = f()。

但是,你可以调用一个方法且忽略返回值。这叫做调用一个函数的副作用,因为你不在乎返回值,只是想利用方法做些事。所以如果你直接调用 f(),Java 编译器就不知道你想调用哪个方法,阅读者也不明所以。因为这个原因,所以你不能根据返回值类型区分重载的方法。为了支持新特性,Java 8 在一些具体情形下提高了猜测的准确度,但是通常来说并不起作用。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:api网站api接口工具(api 工具)
下一篇:龙邦快递物流查询单号查询(龙邦物流快递单号查询快速)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~