Point3D是Point2D的子类,它们有同名的成员变量,在main最后的for中调用offset()改变坐标:
Point2D的对象可以成功,但Point3D的对象不可以!为什么呢?
  
   另外,当Point3D中不声明int x,y时,也就是直接继承Point2D中的x,y就可以成功调用offset()函数了?为什么呢?   大神指教呀!先谢了public class Point2D {
protected int x,y;

Point2D(){};   //无参构造函数

Point2D(int x1,int y1)  //构造函数
{
x=x1;
y=y1;
}

public void offset(Point2D p)  //随机平移
{
p.x+=(int)(java.lang.Math.random()*100);
p.y-=(int)(java.lang.Math.random()*1000);
}

public String showContent()  //打印坐标
{
return "("+x+","+y+")";
}
}public class Point3D extends Point2D{ private int x,y,z;
//private int z;

Point3D(int x1,int y1,int z1)  //子类必须调用父类的构造函数,所以在Point2D中要写Point2D(){}
{
//super();
x=x1;
y=y1;
z=z1;
}

Point3D(Point2D p,int z1)  //构造函数
{
super(p.x,p.y);
x=super.x;
y=super.y;
z=z1;
}

public void offset(Point3D p)  //随机平移
{
p.x+=(int)(java.lang.Math.random()*10);
p.y-=(int)(java.lang.Math.random()*1000);
p.z+=(int)(java.lang.Math.random()*100);
}

public String showContent()   //打印坐标
{
return "("+x+","+y+","+z+")";
}


    public static void main(String[] args) {
// TODO Auto-generated method stub
double dist=0;  //记录两点间的距离

/*Point2D 对象*/
Point2D p2d1=new Point2D(3,5);
Point2D p2d2=new Point2D(4,1);
dist=java.lang.Math.sqrt((p2d1.x-p2d2.x)*(p2d1.x-p2d2.x)+(p2d1.y-p2d2.y)*(p2d1.y-p2d2.y));
System.out.println("二维空间两点之间距离为:"+dist);

/*Point3D 对象*/
Point3D p3d1=new Point3D(3,5,7);
Point3D p3d2=new Point3D(p2d2,1);
dist=java.lang.Math.sqrt((p3d1.x-p3d2.x)*(p3d1.x-p3d2.x)+(p3d1.y-p3d2.y)*(p3d1.y-p3d2.y)+(p3d1.z-p3d2.z)*(p3d1.z-p3d2.z));
System.out.println("三维空间两点之间距离为:"+dist);

/*随机生成Point2D,Point3D的对象*/
double rand=-1;   //存储随机数
Point2D array[]=new Point2D[10];  //声明对象数组
int count=0;     //计数变量
while(count<10)
{
rand=java.lang.Math.random();  //生成随机数
if(rand>=0 && rand<=0.5)  //分条件存储
{
array[count]=new Point2D((int)(rand*100),(int)(rand*1000));
}
else
{
array[count]=new Point3D((int)(rand*10),(int)(rand*100),(int)(rand*1000));
}

count++;
}

/*输出各个对象对应坐标,以确定是Point2D,Point3D的对象*/
System.out.println("平移前"+"                                     "+"平移后"); 
for(count=0;count<10;count++)
{
System.out.print(array[count].showContent());  //当子类和父类有完全相同的函数时,不用super,默认调用子类自己的
array[count].offset(array[count]);          //每个对象随机平移
System.out.print("              ");
System.out.println(array[count].showContent()); 
}

/*Point3D ppp=new Point3D(1,2,3);
System.out.println(ppp.showContent()); 
ppp.offset(ppp);
System.out.println(ppp.showContent()); */
}
}

解决方案 »

  1.   


    //子类的offset方法
    public void offset(Point2D p1) // 随机平移
    {
    Point3D p = (Point3D)p1;
    p.x += (int) (Math.random() * 10);
    p.y -= (int) (Math.random() * 1000);
    p.z += (int) (Math.random() * 100);
    }这样才算重写。你那样就不是重写父类方法了。试试
      

  2.   


    这个的确可以了,但我写的为啥不行呢?我在Point3D中如果只定义成员变量int z;就可以了?   求解释呀
      

  3.   


      如果array[count]中放的是Point3D的对象引用,难道
      array[count].offset(array[count]) 不能调用Point3D能定义的offset()吗???         
      

  4.   

    我的意思是这个程序。你的意思?不是很明白。class Point2D {
    protected int x, y; Point2D() {

    } Point2D(int x1, int y1){
    x = x1;y = y1;
    } public void offset(Point2D p) // 随机平移
    {
    System.out.print("super");
    p.x += (int) (java.lang.Math.random() * 100);
    p.y -= (int) (java.lang.Math.random() * 1000);
    } public String showContent() // 打印坐标
    {
    return "(" + x + "," + y + ")";
    }
    }public class Point3D extends Point2D {
    private int z;
    Point3D(int x1, int y1, int z1){
    x = x1;y = y1;z = z1;
    }
    Point3D(Point2D p, int z1){
    x = p.x;y = p.y;z = z1;
    }
    public void offset(Point3D p) // 随机平移
    {
    System.out.print("sub");
    p.x += (int) (Math.random() * 10);
    p.y -= (int) (Math.random() * 1000);
    p.z += (int) (Math.random() * 100);
    } public String showContent()// 打印坐标
    {
    return "(" + x + "," + y + "," + z + ")";
    } public static void main(String[] args) {
    //...省略,为了简洁
    /* 随机生成Point2D,Point3D的对象 */
    double rand = -1; // 存储随机数
    Point2D array[] = new Point2D[10]; // 声明对象数组
    int count = 0; // 计数变量
    while (count < 10) {
    rand = Math.random(); // 生成随机数
    if (rand >= 0 && rand <= 0.5){
    array[count] = new Point2D((int)(rand * 100),(int)(rand * 1000));
    } else {
    array[count] = new Point3D((int)(rand * 10),
    (int)(rand * 100),(int)(rand * 1000));
    }
    count++;
    } /* 输出各个对象对应坐标,以确定是Point2D,Point3D的对象 */
    System.out.println("平移前\t\t\t平移后");
    for (count = 0; count < 10; count++) {
    System.out.print(array[count].showContent()); // 当子类和父类有完全相同的函数时,不用super,默认调用子类自己的
    array[count].offset(array[count]); // 每个对象随机平移
    System.out.print("\t\t");
    System.out.println(array[count].showContent());
    }
    }
    }
      

  5.   

    你的offset方法没有覆盖,而array[]数组在最初定义的是point2D类型,当这个数组中出现point3D元素时候,相当于是这样一个形式:Point2D array[count]=new Point3D(int ,int, int),所以当调用offset方法时候是找Point2D中的offset方法。然后在Point3D中,你自己有定义了x和y变量,将Point2D中的x和y隐藏了,因此就找不到相应的x和y来计算位移了。造成了前后两次坐标都没变化。
      

  6.   

      感激以上两位的回答。
      问题解决了,主要在Point3D中写offset()方法是出错了。不算是多态!!!
      由于array[count]是POint2D类型的,所以即使array[count]存放的point3D对象的引用,
    任然会调用其从父类调用得来的offset()方法。   解决方法就是:重写offset()方法。1.不带参数   2.带上一个Point2D类型参数,在函数体
    内强制转换成Point3D类型