提问,Java的重载和重定义的底层实现原理是什么

问题描述

最近遇到个问题(不常用的那种)让我对Java的重载和重写有点迷惑,请高手指正。代码和结果如下:class Cat{}class WhiteCat extends Cat{}class BlackCat extends Cat{}public class test { public void feed(BlackCat cat){ System.out.println("feed BlackCat"); }public void feed(Cat cat){ System.out.println("feed cat"); } public void feed(WhiteCat cat){ System.out.println("feed WhiteCat"); } public static void main(String[] args) { Cat wc = new WhiteCat(); Cat bc = new BlackCat(); test p = new test(); p.feed(wc); p.feed(bc); }输出的结果是:feed catfeed cat有高手能详细的解释下 动态多单分配和静态多分配的实现机制么?比如重写,是在加载类的时候从基类往子类加载到栈中,找的时候从栈顶网栈底找,所以当方法名和参数一样的时候只找到子类就返回,基类的方法就被屏蔽了。(貌似不完整,有更明确的说明吗)那动态多分配的情况是怎么实现呢?问题补充恩,好好研究研究问题补充有点明白了,传进来的参数,不是看class本身的类型,而是看指引的类型。不过静态多分配和动态单分配的问题还是有疑惑,希望有高手继续指点。另外谢谢楼上的

解决方案

其实这个和java语言本身的性质有关:对于重载,是编译时静态绑定的。所以        Cat wc = new WhiteCat();        p.feed(bc); wc定义的类型是Cat,编译的时候绑定到了 public void feed(Cat cat)而多态是动态绑定,即运行时确定,所以WC,BC的同一个方法会有不同的行为:如:class Cat{    public void fun(){       System.out.println("Cat");    }}class WhiteCat extends Cat{    public void fun(){       System.out.println("Whilte Cat");    }}class BlackCat extends Cat{    public void fun(){       System.out.println("Black Cat");    }} Cat wc = new WhiteCat();wc.fun();输出;Whilte Cat
解决方案二:
p.feed(wc); p.feed(bc);选择overload方法是编译时根据传参的声明类型决定的。wc和bc都已经声明为Cat类型,因此编译器选择了Test.feed(Cat)方法。Groovy的方法查找机制是依赖于参数的实际类型,所谓的multimethods。可以参考《Groovy In Action》7.3.3
解决方案三:
p.feed(wc); p.feed(bc); wc, bc变量声明为 Cat类型,不管wc,bc 实际指向的是Cat还是Cat的子类, 最终会解释为Cat,与p.feed(bc);p.feed(wc);匹配的方法只有下面这个。 public void feed(Cat cat){ System.out.println("feed cat"); }结果当然是调用的同一方法public void feed(Cat cat)。
解决方案四:
方法的重载① 有多个相同名称的方法② 它们的形参类型或个数是不同③ 构造器的名称必须和类名相同且没有返回值,每个类可以有一个以上的构造器,但构造器的方法签名必须不同。public class OverloadTest {int add(int i, int j) { return i + j; }double add(double i, double j) { return i + j; }float add(float i, float j) { return i + j; }int add(int a){ return b; }void display() { System.out.println("what's your name?"); }void display(String name) { System.out.println("Hello " + name + "!"); }public static void main(String[] args) {OverloadTest obj = new OverloadTest();int a = 1 , b = 2;double c = 3.3, d = 4.4;float e = 2f, f = 4f;System.out.println("result: " + obj.add(a, b));方法的重写集成了父类的方法,觉得不适合自己的业务需要,需要重写父类的方法,叫方法的重写
解决方案五:
子类赋给基类的引用。这么做相当于传了一个父类的参,如果是BlackCat bc = new BlackCat(),输出应该就是 feed BlackCat
解决方案六:
lz肯定明白java的参数传递,本例中传递的值是Cat cat = new BlackCat() or WhiteCat(); 也就是cat这个Cat类型的引用 指向的是黑猫或者白猫的对象,但是传递的仍是Cat 的引用。。 要区分开的是:如果在此cat引用上调用方法时,就用根据引用指向的对象去调用对应的方法.. 这是我的理解.
解决方案七:
深入java虚拟机 这本书上有解。。

时间: 2024-09-07 00:37:52

提问,Java的重载和重定义的底层实现原理是什么的相关文章

运算符重载-用C++编程:定义一个四进制的类,重定义“+”号实现四进制数的累加。

问题描述 用C++编程:定义一个四进制的类,重定义"+"号实现四进制数的累加. 定义一个四进制的类,重定义"+"号实现四进制数的累加. 输入第一行输入所需要的四进制数的个数第二行开始,依次输入四进制数 输出所有输入四进制数累加的和 解决方案 又是作业贴啊,要是做的过程中有问题,LZ直接说遇到的问题吧 解决方案二: 我写了个简单的,你试试好用不,没有做输入判断,你输入一定不能输4或者4以上的数123+321+333=2103 #include ""

避免对派生的非虚函数进行重定义

今天无意中发现一个关于C++基础的问题,当时愣是没理解是什么原因,现在搞明白了,就写下来了 .先看小程序,先实践再理论吧,要不大家就睡着了. #include <iostream> using namespace std; class Base { public: virtual void funtion(int arg = 1){cout<<arg<<endl;} }; class Derive : public Base { public: virtual void

class-为什么说java中一个类中定义两个构造函数。

问题描述 为什么说java中一个类中定义两个构造函数. 为什么说java中一个类中定义两个构造函数.是不是意思就是一个是无参构造函数,一个是有参数的构造函数, 解决方案 构造函数可以定义很多个,如同函数重载,只要参数个数类型不同就可以. 因此无参构造函数只能有一个.至于定义2个,可以是一个无参,一个有参,也可以是2个有参. 解决方案二: oh no, an object can have multiple constructors with different parameters. 解决方案三

remove-[菜鸟提问] Java关于Interator的问题

问题描述 [菜鸟提问] Java关于Interator的问题 问题一 如上面两图所示,为啥在循环体中先"remove"后"print"结果"云南铜业"还是能被打出来? 问题二 为什么不让Stocks直接继承Interator,然后遍历,却要赋值给Interator I? 问题三 ..为啥继承接口报错.... 不好意思问的会不会太多.... 解决方案 另外,下次贴出完整代码,而不是截图,这样比较容易办你调试,而且完整的代码更容易告诉你错在哪里. 记

java 抽象类与接口的定义

java  抽象类与接口的定义 Jvm : 抽象规范: 一个具体实现 一个运行的虚拟机实例 装载器: 启动类装载器,自定义装载器(继承 java.lang.ClassLoader ) 解析的内型信息放入方法区,对象放入堆,一个新线程,有自己 java 栈放中间数据, pc 计数器. 接口与抽象类深入 java 没有多重继承,意味一个类只能继承一个父类所以绝对必要的时候,才用继承 所以表示相同行为的方法都应该声明为一个接口的的形式,并使用不同的实现类对其进行实现. 缺点:每一个实现类都需要显示的实

实例分析java中重载与重写的区别_java

本文以实例详细分析了Java中重载与重写的区别,感兴趣的朋友可以参考一下. 一.重载(Overloading): (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现. (2)Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义. 调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性. (3) 重载的时候,方

对象-java中构造方法simpleadapter没有定义好是什么原因造成的???

问题描述 java中构造方法simpleadapter没有定义好是什么原因造成的??? The constructor SimpleAdapter(new View.OnClickListener(){} List> int String[] int[]) is undefined 有时候系统提示加:我也加了:但是eclipse还是报错是什么原因造成的 解决方案 是编译错误还是运行时错误呢? 解决方案二: 把你代码贴出来看看.

用Oracle9i在线表格重定义来重新组织表格

在Oracle9i出现之前,你只能通过导出和导入的方式来进行表格重定义,因此表格重定义的过程是一个离线过程.甚至在线变化("ALTER TABLE ADD NEW_COL NUMBER(3)")也会导致独占性死锁(exclusive locks),这就需要在DDL完成之前防止所有DML(插入.更新)的运行. 为了解决这个问题,Oracle9i在其DBMS_REDEFINITION软件包中引入了在线表格重定义功能.有了DBMS_REDEFINITION软件包,你就可以:   1.拷贝表格

提前认识软件开发(5) 重定义一些基本数据类型

在编写程序的时候,定义变量是必不可少的,这时就要用到一些基本数据类型. 也许你会说,定义一个变量有什么困难的,这是很容易办到的.要定义整型变量,直接用"int i;"语句就可以了:要定义字符型变量,直接用"char c;"就可以了.确实,这是学校教育教给我们的,但在实际工作中却不能这样做. 为什么呢?原因很简单,因为这样写出来的程序,看起来很"山寨",不是专业的程序员应该做的事情. 前段时间,我在看<楚汉传奇>,有一个场面给我留下了非