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说,这锅我不背.
通过返回值来区分重载方法可不可以?
不可以,不用多说.因为返回值不是函数签名的一部分.是没有办法区分方法调用的.
TIJ读书笔记04-方法重载的更多相关文章
- TIJ读书笔记06-终结清理和垃圾回收
TIJ读书笔记06-终结清理和垃圾回收 finalize()方法 垃圾回收器如何工作 java的垃圾回收是由jvm来控制的.所以需要java程序员参与的部分不是很多. 但是在这里需要明白一点,java ...
- TIJ读书笔记05-this关键字
TIJ读书笔记05-this关键字 概述 this的用法 static方法 概述 两个对象同时调用一个方法,那么jvm怎么知道是哪个方法调用的呢. 我们在书写的时候会写成a.fun(1) 或者b.fu ...
- TIJ读书笔记03-初始化和构造器
TIJ读书笔记03-初始化和构造器 初始化和清理是涉及安全的两个问题,如果对象不能正确的初始化会引起很多错误,比如空指针异常等,如果不能恰当及时的清理,会占用过多资源. 构造器在创建一个类的实例的 ...
- TIJ读书笔记02-控制执行流程
TIJ读书笔记02-控制执行流程 TIJ读书笔记02-控制执行流程 if-else 迭代 无条件分支 switch语句 所有条件语句都是以条件表达式的真假来决定执行路径,也就是通过布尔测试结果来决 ...
- TIJ读书笔记01-操作符
TIJ读书笔记01-操作符 概述 关系操作符和逻辑操作符 位操作符 类型转换 概述 操作符 操作符接受一个或多个参数,并生成一个新值. 换句话说操作符作用于操作数,生成一个新值.有些操作符会改变操 ...
- TIJ读书笔记08-数组的初始化和可变长参数形参
TIJ读书笔记08-数组的初始化和可变参数形参 数组 数组的声明 数组的初始化和赋值 可变参数列表 数组 相同类型的,用一个标识符名称封装到一起的一个对象序列或者基本数据类型序列叫数组.(多么严谨的概 ...
- Java学习笔记之方法重载,动态方法调度和抽象类
一.方法重载 如果子类中的方法与它的超类中的方法有相同的方法名,则称子类中的方法重载超类中的方法,特别是当超类和子类中的方法名和参数类型都相同时,在子类中调用该方法时,超类中的方法会被隐藏.考虑下面程 ...
- Java学习笔记之——方法重载
方法重载: overload 1. 方法签名 组成:方法名(参数列表) 参数列表不同分为哪些情况? (1)有无参数 (2)参数的类型 (3)参数的个数 (4)参数的顺序(前提是类型不一样) 2.方法重 ...
- [Clr via C#读书笔记]Cp8方法
Cp8方法 构造器 作用就是初始化所有成员字段:.ctor:派生类和基类都有自己的构造函数.默认有一个无参数的构造函数,值字段初始化为0,引用字段初始化为null:可以有多个构造器: 值类型的初始化其 ...
随机推荐
- HttpContext.Current.Cache 和HttpRuntime.Cache的区别
先看MSDN上的解释: HttpContext.Current.Cache:为当前 HTTP 请求获取Cache对象. HttpRuntime.Cache:获取当前应用程序的Cac ...
- <jsp:include>和<%@ include %>的区别
使用<%@ include %>指令元素只是将页面的内容静态的包含进来,如果被包含的文件中有JSP代码,则会执行该代码,而不管该文件是否为动态文件. <jsp:include> ...
- js中Math.round、parseInt、Math.floor和Math.ceil小数取整总结
Math.round.parseInt.Math.floor和Math.ceil 都可以返回一个整数,具体的区别请看下面的总结. 一.Math.round 作用:四舍五入,返回参数+0.5后,向下取整 ...
- python数据结构与算法——图的最短路径(Bellman-Ford算法)解决负权边
# Bellman-Ford核心算法 # 对于一个包含n个顶点,m条边的图, 计算源点到任意点的最短距离 # 循环n-1轮,每轮对m条边进行一次松弛操作 # 定理: # 在一个含有n个顶点的图中,任意 ...
- SPARQL1.1 101 Language and Jena support
1 introduction definition cited from SPARQL 1.1 Overview: SPARQL 1.1 is a set of specifications that ...
- hdu4686 Arc of Dream ——构造矩阵+快速幂
link: http://acm.hdu.edu.cn/showproblem.php?pid=4686 构造出来的矩阵是这样的:根据题目的ai * bi = ……,可以发现 矩阵1 * 矩阵3 = ...
- hdu4666 Hyperspace ——曼哈顿距离
link:http://acm.hdu.edu.cn/showproblem.php?pid=4666 这题学会了怎么处理曼哈顿距离. 比如维数是k,那么每个点有2^k个状态,求出在每个状态下,所有点 ...
- kuangbin_MST B (POJ 1287)
裸的模板题 因为直接用的邻接矩阵所以用最小值覆盖先前输入的重复边 #include <cstdio> #include <cstring> #include <queue ...
- 基于MVC4+EasyUI的Web开发框架形成之旅--权限控制
我在上一篇随笔<基于MVC4+EasyUI的Web开发框架形成之旅--框架总体界面介绍>中大概介绍了基于MVC的Web开发框架的权限控制总体思路.其中的权限控制就是分为“用户登录身份验证” ...
- Jmeter--HTTP Cookie管理器
一.什么情况下需要用到Cookie 一般情况下对于HTTP请求的用户登入操作,需要用到Cookie来模拟用户操作,或者对一些业务只有在用户登入之后才能进行操作,比如:常见的场景有购买商品.下单.支付等 ...