尝试写三个类,但是出现了比较怪异的现象,实在是想不通,希望高人指点一二。
===============================
package overridtest;
//filename : Dog.javapublic class Dog{
void cry(){
System.out.println ("wang wang !");
}
}
=============================
package overridtest;
//filename:YellowDog.javapublic class YellowDog extends Dog{
void cry(){
System.out.println ("wang show !");
}
void cry(int i){
System.out.println("wang "+i);
}
}
==============================
package overridtest;
//filename:test.javaclass Test{
public static void main(String[] args)
    {
     YellowDog test = new YellowDog();//yes
     //Dog test = new YellowDog();//no
     test.cry();
     test.cry(2);
    }
}
=================================编译前两个java文件时没有问题,而且是先编译的,但是后面一个java文件编译时就出现问题,注释为yes的方法是可以的,注释为no的方法是错误的。

解决方案 »

  1.   

    //Dog test = new YellowDog();//no
         test.cry();
         test.cry(2); // 错就错在这里,因为你的Dog中,没有声明cyr(int)的方法,
    修改如下:
    public class Dog{
    void cry(){
    System.out.println ("wang wang !");
    }
             void cry(int i)
             {}
    }这样,加入一个空的方法就能都编译过了。
      

  2.   

    问题是test对象是根据YellowDog()构造方法构造出来的,为什么没有cry(int)方法?cry(int)方法在YellowDog()中已经定义了啊?
      

  3.   

    你声明的时候用了
    Dog test = new YellowDog();
    也就是,你声明的时候是用的Dog类,
    此时,test是Dog类的一个对象,而不是YellowDog的对象。
    Dog中没有cry(int)方法。
      

  4.   

    你这么看吧。
    Dog test = null;
    // .....中间这些先略掉一部分代码
    test.cry(2);你看上面几行,你觉得是正确的吗?
    很明显是错误的,对吧?无论中间省掉了什么代码,都不对。然后我们加上略掉的一行:
    test = new YellowDog();然后你认为那个错误的程序会变正确吗?
      

  5.   

    多谢这么快速回答问题。
    我现在不是很清楚的问题是,在test对象被创建的时候是根据Dog被创建的,但是如果程序修改为:
    package overridtest;
    //filename : Dog.javapublic class Dog{
    void cry(){
    System.out.println ("wang wang !");
    }
    void cry(int i){
    System.out.println ("wang wang !");
    }
    }
    =======================================
    package overridtest;
    //filename:YellowDog.javapublic class YellowDog extends Dog{
    void cry(){
    System.out.println ("wang show !");
    }
    void cry(int i){
    System.out.println("wang "+i);
    }
    }
    ===================================
    package overridtest;
    //filename:test.javaclass Test{
    public static void main(String[] args)
        {
         //YellowDog test = new YellowDog();//yes
         Dog test = new YellowDog();//no
         test.cry();
         test.cry(2);
        }
    }
    ================================
    其结果又是:
    wang show !
    wang 2
    表示其调用的方法还是YellowDog中定义的方法。这个是不是说构造方法决定对象调用方法?
      

  6.   

    看来我的问题出在重写上了,呵呵!
    望masse能解释一下在这个例子中内存划分详细的情况,我的分析是:
    Dog test;这句执行后内存栈中划分了一个可以用来存放地址空间名称为test,可以用来存放基于Dog类创建的对象空间的地址。
    test = new YellowDog();这句的执行则根据Dog的子类YellowDog划分了一个空间,其中包括YellowDog中所有成员(当然也就包括了void cry(int i)成员方法),然后将这个空间首地址赋值给test这个引用数据类型变量。
    所以我就想当然认为先重写,然后在重写基础上重载也是可以调用的方法。
    希望指出不足之处。多谢!
      

  7.   

    override好像翻译就是重写吧。
      

  8.   

    YellowDog test = new YellowDog();
    Dog test1 = new YellowDog();
    test.cry();
    test1.cry();
    test.cry(2);
    ((YellowDog)test1).cry(2);
    //这样就可以了,使用一下强制类型转换,test1是dog类型句柄,没有cry(int)这个方法的,虽然它运行时实际对象是YellowDog类型,但是编译器并不知道。
      

  9.   

    override一般翻译成“覆盖”,老的教材用“重写(overwrite)”,Java已经不用这个术语了。
      

  10.   

    用类似于C的方式来解释这个问题比较容易,其实Dog test = new YellowDog();中的test指向的空间是有cry(int)方法的,只不过指针的移动由指针的声明数据类型决定,所以test的调用方法由Dog决定,所以不能移动到方法cry(int)的内存区域,从而也就不能调用cry(int)方法了,rumlee(rum-lee)的强制转换类型似乎就能说明这个问题。结贴吧!