近日,学习Java时,看到如下程序,有一个问题想不明白,希望大家帮忙看看
abstract class Geometry{
  public abstract double ComputerArea();
}
class Lader extends Geometry{
  double a,b,h;
  Lader(double a,double b,double h){
    this.a = a;
    this.b = b;
    this.h = h;
    }
  public double ComputerArea(){
    return((1/2.0)*(a+b)*h);
    }
}
class Cone{
  Geometry bottom;
  double height;
  Cone(Geometry bottom,double height){
    this.bottom = bottom;
    this.height = height;
    }
  void changeBottom(Geometry bottom){
    this.bottom = bottom;
    }
  public double ComputerVolume(){
    return(bottom.ComputerArea()*height)/3.0;
    }
}
public class GraphicsTest{
  public static void main(String[] args){
    Cone cone;
    Geometry geometry;
    geometry = new Lader(2.0,7.0,10.7);//对象的上转型
    System.out.println("梯形的面积" + geometry.ComputerArea());//输出面积,都没有问题
    cone = new Cone(geometry,30);//问题
    System.out.println("梯形底的椎的体积" + cone.ComputerVolume());
    }
}
问题?
在这里的第一个参数为geometry类型的,它的值是什么,从哪里来的??
根据输出的结果可以判定geormetry的值是geormetry.ComputerArea()的值,为什么?

解决方案 »

  1.   

    >在这里的第一个参数为geometry类型的,它的值是什么,从哪里来的??geometry = new Lader(2.0,7.0,10.7);//对象的上转型就是这一句 new 出来的一个 Lader 的实例呀,楼主不清楚吗?
      

  2.   

    确实,在geometry = new Lader(2.0,7.0,10.7);中,new出实例,可是我一直认为实例是用来调用成员变量或方法用的,其具体里面有什么不是很清楚。
        如果有值得话,值是怎么分配的?为什么就是geometry.ComputerArea()的值?谢谢!
      

  3.   

    是我一直认为实例是用来调用成员变量或方法用的,其具体里面有什么不是很清楚。
    ----------------------------------------------
    是啊,public double ComputerVolume(){
        return(bottom.ComputerArea()*height)/3.0;
        }
    这里不是调用了实例的方法了么?
    cone = new Cone(geometry,30);//问题
    这是以一个Geometry和一个double型构造了一Cone对象,Cone对象里有成员变量Geometry,可以调用其方法
      

  4.   

    楼主没学过OOP建议看书---初学者
      

  5.   

    //根据输出的结果可以判定geormetry的值是geormetry.ComputerArea()的值,为什么?你从哪儿看到“geormetry的值是geormetry.ComputerArea()的值”了?
    geormetry是一个对象实例的引用,它当然有值,但是它的值只是为了指示实例的位置。
    在Cone中也是用了
       return(bottom.ComputerArea()*height)/3.0;什么地方直接用geormetry本身的值了?
      

  6.   

    cone = new Cone(geometry,30);中不是就用到geormetry的值了么??
    那个值是从哪里来的??
      

  7.   

    geometry = new Lader(2.0,7.0,10.7);//对象的上转型   实例化了类lader而类lader 又是从Geometry 继承来的,
    所以   cone = new Cone(geometry,30);//问题 
    这里的参数 geometry 就是一个实实在在的对象了!
      

  8.   

    楼主对Object的基本概念不甚了解,建议看一下书。
      

  9.   

    我已经说了geormetry是一个对象实例的引用,它是有值的,它的值只是为了指示对象实例的位置,cone = new Cone(geometry,30);这样确实把geometry的值传了进去,使得成员变量bottom和geometry指向同一个实例,这样就可以通过bottom.ComputerArea()来取得方法ComputerArea()的返回值,
    还是那个问题,你从什么地方看出来“geormetry的值是geormetry.ComputerArea()的值”了?
      

  10.   

    geormetry代表一块内存空间叫做对象
    geormetry.xxx可以提取此空间的值,或则调用储存的函数
      

  11.   

    如果理解为 geormetry这个引用的实例是geormetry.ComputerArea()的返回值
    对吗??刚开始学,确实有许多地方不明白,
    而且这些在书中也没有讲到。这是一个书上的,例题。谢谢大家了!
      

  12.   

    哈,我看到了楼主的障碍了,年度最佳教练来带你走出这个巨大的误区。:)学习面向对象的语言,有两样东西楼主必须搞清楚——类型和对象。楼主的问题在哪里呢?楼主不能够区分两种类型。JAVA 和 C# 中都是只有两种类型,一种是值类型(JAVA 教材中称简单类型),另一种是引用类型。void add(int i, int j) { ……}如果这样用 add(1, 2) 我想楼主一定可以理解的,为什么楼主理解了呢?因为楼主理解值类型。那么,楼主为什么不能够理解 cone = new Cone(geometry,30) 呢?就是因为楼主完全没有理解引用类型。什么是引用类型呢?不是值类型的类型都是引用类型。值类型是什么呢?很少,只有整型、浮点型、字符型和布尔型这四种。除此之外,数组、字符串以及你自己写的(如HelloWorld)及别人写的类型都是引用类型。两种类型有什么不同呢?值类型是编译器直接支持的类型,因此你从未见过 class int 或者 class char 这样的类型定义。值类型中只能够包含一个值(楼主已经理解了),而引用类型则可以包含大千世界。但是,当你 (geometry,30) 这样使用一个引用类型时,会将一个引用类型的地址传递给被调用的方法,在被调用的方法中,并不是仅仅接收到一了个值,而是接到了一个引用,可以通过这个引用可以访问被引用对象的方法和属性。如果楼主一定要认为 (geometry,30) 传递了一个值,那么也是不错的,这个调用确实传递了一个值,这个值就是 geometry 这个变量的内存起始地址,在 32 位机器上,就是一个 32 位的整形值。但楼主必须清楚,这个值并不能够代表 geometry 的内部世界,它只是一个通往那个世界的法门,一个入口。希望楼主不会说“还是不清楚”,年度最佳教练丢不起这个人。:)
      

  13.   

    哈哈,谢谢,能得到年度最佳教练的指导,深感荣幸经过你这么一说,确实明白了许多,但是还有一个问题
    就是(geometry,30)中的geormetry是怎么找到需要的值的??楼上flyforlove说过是通过cone = new Cone(geometry,30);把值传过去的
    可是在Cone(Geometry bottom,double height){
        this.bottom = bottom;
        this.height = height;
        }
    中,我怎么没有看出来! bottom也是Geormetry类型, geormetry也是Geormetry类型,
    两个引用具有相同的地址,可这两个引用我没有发现引用的值是什么??谢谢!!!
      

  14.   

    JAVA 中只有传值调用,如果传递的是一个引用类型,那么这个值就是引用类型的内存地址。楼主可以这样看到这个地址值:Object o = this;
    System.out.println(o);这个年度最佳教练我就不再当了。:(
      

  15.   

    从代码里面看,主方法调用先声明Geometry类的一个对象geometry,然后Lader类是继承Geometry父类的子类。由于Lader类是继承Geometry父类的子类所以对象geometry也同样可以用Lader类来定义。“geometry = new Lader(2.0,7.0,10.7);//对象的上转型”这一句就是将(2.0,7.0,10.7)复值Lader类。并且将返回值(对象geometry出现值的关键代码:public double ComputerVolume(){return(bottom.ComputerArea()*height)/3.0;})给对象geometry。
    这就是你问题的答案!
      

  16.   

    首先再次感谢doway(john)的解答,多谢帮忙,你的讲解让我明白了许多,谢谢!楼上的解释,我明白了.
    说说我的想法: 
    我一直认为函数的返回值是在对象的引用在调用方法时,利用其返回值得到一个数而已
    没有想过能将返回值传给对象,这个是什么原理?
    这几天我也一直在查阅相关资料,但是都没有找到理想的答案
    所以能讲一下将返回值传给对象的原理么??再次谢谢大家!
      

  17.   

    “将返回值传给对象”的说法是不正确的。楼主需要找的书是计算机基础原理和 JAVA 的内存布局,要搞清楚栈和堆的概念,以及传值调用的含义。不能再了,楼主你让本教练无地自容了,以后就靠自己吧。送楼主一句我刚刚学会没几天话——书是药,多看医笨。:)