尝试写三个类,但是出现了比较怪异的现象,实在是想不通,希望高人指点一二。
===============================
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的方法是错误的。
===============================
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的方法是错误的。
test.cry();
test.cry(2); // 错就错在这里,因为你的Dog中,没有声明cyr(int)的方法,
修改如下:
public class Dog{
void cry(){
System.out.println ("wang wang !");
}
void cry(int i)
{}
}这样,加入一个空的方法就能都编译过了。
Dog test = new YellowDog();
也就是,你声明的时候是用的Dog类,
此时,test是Dog类的一个对象,而不是YellowDog的对象。
Dog中没有cry(int)方法。
Dog test = null;
// .....中间这些先略掉一部分代码
test.cry(2);你看上面几行,你觉得是正确的吗?
很明显是错误的,对吧?无论中间省掉了什么代码,都不对。然后我们加上略掉的一行:
test = new YellowDog();然后你认为那个错误的程序会变正确吗?
我现在不是很清楚的问题是,在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中定义的方法。这个是不是说构造方法决定对象调用方法?
望masse能解释一下在这个例子中内存划分详细的情况,我的分析是:
Dog test;这句执行后内存栈中划分了一个可以用来存放地址空间名称为test,可以用来存放基于Dog类创建的对象空间的地址。
test = new YellowDog();这句的执行则根据Dog的子类YellowDog划分了一个空间,其中包括YellowDog中所有成员(当然也就包括了void cry(int i)成员方法),然后将这个空间首地址赋值给test这个引用数据类型变量。
所以我就想当然认为先重写,然后在重写基础上重载也是可以调用的方法。
希望指出不足之处。多谢!
Dog test1 = new YellowDog();
test.cry();
test1.cry();
test.cry(2);
((YellowDog)test1).cry(2);
//这样就可以了,使用一下强制类型转换,test1是dog类型句柄,没有cry(int)这个方法的,虽然它运行时实际对象是YellowDog类型,但是编译器并不知道。