zoukankan      html  css  js  c++  java
  • TIJ读书笔记04-方法重载

     

     

    为什么会有方法重载

    OOP的编程方式就是让程序的逻辑更加接近现实世界的逻辑. 而在现实世界中,自然语言本身就是很强的冗余容错能力的. 比如,水有个方法叫洗. 那么在自然语言中,洗车,洗衣服…这都是洗这个方法. 映射到程序语言就是water.wash(car);,water.wash(clothes) 而不会说以洗车的方式洗车water.washCar(car)和以洗衣服的方式洗衣服water.washClothes(clothes)

    java就提供了方法重载机制,一方面,更加接近自然语言逻辑. 另一方面,由于构造方法的存在. 每个类默认都有一个无参构造器,另外如果还想自定义一些构造器的话,由于构造方法的名称是甲鱼的臀部规定好了的. 那么就意味着每个构造器都要有相同的名字. 那么,这就必须要使用重载了.

    方法签名

    首先,一个方法的组成,一个方法由权限修饰符,返回值类型,方法名,形参列表,抛出异常类型和方法体组成.方法是依赖于一个类的,那么对于不同类的同名方法,在调用时是不存在歧义的,所以不用考虑.

    JVM在调用方法的时候是通过方法签名来调用的. 换句话说同一个类中的方法签名应该是唯一的. 在构成方法的所有元素中,能唯一标识一个方法的组合都可以成为方法签名.
    java的做法是将方法名和形参列表的组合作为方法签名. 为什么呢?因为在调用一个方法的时候,这两个是必须显式写出来的. 比如person.fun1("tom",29);

    所以balabala说了那么多,方法签名就是函数名+形参列表

    如何区分重载

    明白了jvm是怎么调用方法的,就可以理解怎么区分重载了. 方法必须有独一无二的函数签名,对于重载方法来说,由于方法名是一样的. 那么能区分签名的就只剩形参列表了. 也就是说,重载方法必须有独一无二的形参列表. 可以是形参的类型不一样,可以是形参的个数不一样,也可以是形参顺序不一样. 但是一般不会采用顺序不一样. 因为这样会难以维护.

    关于基本类型的重载

    package ch5_init;

    public class PrimitiveOverloading {
    public void print(String s){
    System.out.print(s+" ");
    }
    public void f1(char x){print("f1(char)");}
    public void f1(byte x){print("f1(byte)");}
    public void f1(short x){print("f1(short)");}
    public void f1(int x){print("f1(int)");}
    public void f1(long x){print("f1(long)");}
    public void f1(float x){print("f1(float)");}
    public void f1(double x){print("f1(double)");}

    public void f2(byte x){print("f2(byte)");}
    public void f2(short x){print("f2(short)");}
    public void f2(int x){print("f2(int)");}
    public void f2(long x){print("f2(long)");}
    public void f2(float x){print("f2(float)");}
    public void f2(double x){print("f2(double)");}

    public void f3(short x){print("f3(short)");}
    public void f3(int x){print("f3(int)");}
    public void f3(long x){print("f3(long)");}
    public void f3(float x){print("f3(float)");}
    public void f3(double x){print("f3(double)");}

    public void f4(int x){print("f4(int)");}
    public void f4(long x){print("f4(long)");}
    public void f4(float x){print("f4(float)");}
    public void f4(double x){print("f4(double)");}

    public void f5(long x){print("f5(long)");}
    public void f5(float x){print("f5(float)");}
    public void f5(double x){print("f5(double)");}

    public void f6(float x){print("f6(float)");}
    public void f6(double x){print("f6(double)");}

    public void f7(double x){print("f7(double)");}

    public void testConstVal(){
    print("5: ");
    f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5);
    System.out.println();
    }

    public void testChar(){
    char x = 'x';
    print("char: ");
    f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    System.out.println();
    }

    public void testByte(){
    byte x = '0';
    print("byte: ");
    f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    System.out.println();
    }

    public void tesShort(){
    short x = '0';
    print("short: ");
    f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    System.out.println();
    }

    public void testInt(){
    int x = '0';
    print("int: ");
    f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    System.out.println();
    }
    public void testLong(){
    long x = '0';
    print("long: ");
    f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    System.out.println();
    }
    public void testFloat(){
    float x = '0';
    print("float: ");
    f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);
    System.out.println();
    }
    public void testDouble(){
    double x = '0';
    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.tesShort();
    p.testInt();
    p.testFloat();
    p.testDouble();

    }
    }

    这是书上一个很经典的例子. 运行它可以看出来.

    • 常量5: 被当作int值处理.
    • char类型:如果无法找到接收char类型的方法. char类型会被自动转换成int型处理.
    • 对于其他类型: 如果传入的实际类型小于方法声明的参数类型,那么会发生向上转型.
    • 但是如果传入的实际类型大于方法声明的参数类型,需要显示的向下转型.

    万事都要讲理. 类型转换,如果实际类型较小,那么向上转型是没有任何风险的. 精度不会受到影响,最多多占点空间,但是这对现代计算机而言不是什么大事儿. 但是如果实际类型较大,需要向下转型的时候,会发生精度丢失. jvm说,这锅我不背.

    通过返回值来区分重载方法可不可以?
    不可以,不用多说.因为返回值不是函数签名的一部分.是没有办法区分方法调用的.

  • 相关阅读:
    Rain 学习自用贴
    連休計画
    091207 晴
    记下London奥运我喜欢的几首歌
    20世纪最好的10个算法(转)
    一日一美女:告诉你什么是斐波那契螺旋线
    矩阵鞍点的寻找
    日本の物語
    a new start~ s!
    Photoshop CS5运用色彩原理去除半透明水印(转)
  • 原文地址:https://www.cnblogs.com/thecatcher/p/5843970.html
Copyright © 2011-2022 走看看