问题描述
最近遇到个问题(不常用的那种)让我对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虚拟机 这本书上有解。。