有关这些代码
Shape pentagonobj = new Pentagon();Pentagon是shape的子类书上对这代码的解释是:
定义一个pentagonobj 做为子类pentagon的实例
而且它将实现shape类,这样做完全正确 实现多态性时 可以创建一个有父类(如shape类)的对像 但该对像的实际实现是pentagon的!//这句话不明白
也就是说,可以认为对像为shape类型,并且具有对pentagon类型的引用!//这句话更不明白 谁可以用通俗的语言讲一讲这两句话是什么意思  谢谢了!

解决方案 »

  1.   

    父类的引用可以用父类的构造器来创建,也可以用子类的构造器来。
    1. 当用父类构造器来创建时,引用看到的只是父类的方法。
    2. 当用子类构造器来创建时,引用看到的只是父类的方法和那些被子类覆盖掉的方法。Shape pentagonobj = new Pentagon();
    Pentagon是shape的子类这是使用子类的构造器,所以在内存中会按子类来分配内存空间,但引用看到的如上面第二
    条所说的。我们可以通过转换来获得子类的引用,Pentagon pentagon=(Pentagon)pentagonobj .
    为什么可以转换呢?因为我们在前面用的是子类构造器,它就是一个子类,当然可以转换了
      

  2.   

    pentagonobj保留的是一个Pentagon对象的引用,
    子类对象引用可以是父类,但反过来不成立.
    如果 
    Pentagon是shape的子类Pentagon p=new Shape();是不成立的.
      

  3.   

    /*new Pentagon()的时候,jvm会依次装入Pentagon.class和Shape.class,然后实例化。
    实例化的顺序是先创建Shape实例,然后创建Pentagon实例。这一点从构造函数的调用顺序可以看出来。
    “new Pentagon()”操作得到的实际是一个Pentagon类型的指针(其实就是一个内存地址),所以说pentagonobj是个Pentagon类型。
    但是由于多态的存在,它又被upcating成为Shape类型。
    不过upcating后有一点缺陷,就是pentagonobj已经不知道自己是“Pentagon”类型了。
    如果Pentagon类实现了Shape类没有的方法,比如“hello”,那么这个方法不能被直接调用。
    像这样:
    pentagonobj.hello()。是不行的。
    必须这样:
    ((Pentagon)pentagonobj).hello().
    */
    public class Shape
    {
    public Shape()
    {
    System.out.println("Shape");
    }

    public static void main(String[] args)
    {
    new Shape();
    Shape pentagonobj=new Pentagon();
    ((Pentagon)pentagonobj).hello();
    }

    }class Pentagon extends Shape
    {
    public Pentagon()
    {
    super();
    System.out.println("Pentagon");
    }

    public void hello()
    {
    System.out.println("hello");
    }
    }
      

  4.   

    有个很显著的好处就是可以“隔离”代码。这方面thiking in java讲的很清楚,推荐看下。
      

  5.   

    这个问题再怎么抽象地讲也是云山雾罩,不如做个试验一目了然。假定你的Shape类中有一个构造函数,有一个draw方法,如下:
    class Shape {
           public Shape() {
                 System.out.println("在Shape的构造函数中。");
           }
           public void draw() {
                 System.out.println("Shape类的draw方法。");
           }
    }class Pentagon extends Shape{
           public Pentagon () {
                 System.out.println("在Pentagon 的构造函数中。");
           }
           public void draw() {
                 System.out.println("Pentagon 类的draw方法。");
           }
           public void paint() {
                 System.out.println("Pentagon 类的paint方法。");
           }
    }到现在为止,我们有两个类,Pentagon继承Shape,两个类都有一个构造函数和一个draw()方法,Pentagon还有一个Shape没有的方法paint();到现在为止,我们可以静态地看到它们的共同点和不同点,是吧?
    好,现在把它们放到程序中去运行,看看它们的表现。
    public class Poly {
          public static void main(String[] args) {
                    Shape obj = new Pentagon();
                    obj.draw();
          }编译运行,结果为:
    在Shape的构造函数中。
    在Pentagon 的构造函数中。
    Pentagon 类的draw方法。现在对照结果回答楼主的问题:
    1。该对像的实际实现是pentagon的(类):没错,因为obj调用的是Pentagon的draw方法,所以obj实现的Pentagon类
    2。可以认为对像为shape类型,并且具有对pentagon类型的引用:为了印证这句话,现在我们在main方法中加上obj.paint();再编译,咦,程序报错,说找不到paint方法。为什么?
    就是因为obj是Shape类型,而Shape类中并没有paint()方法。关于“具有对pentagon类型的引用”,就不讲了,估计越讲越乱。但到此为止,我们至少明白了两点,1。obj是Pentagon类型因为当调用draw方法时他调用的是Pentagon的draw方法;2。obj是Shape方法因为它不认Pentagon特有的paint方法。换句话说obj兼有Shape和Pentagon两个类的共同点。
    现在回答楼主的第三个问题:
    3。那多态到底有什么好处啊?首先,好处是大大地。我们知道数组可以很方便的定义一系列数据而不必一个一个定义,但有一个缺点,就是每个数组成员的类型必须一样。但有时我们确实需要这样的数组,怎么办,有了多态,问题就好办了。比如,我们有Pentagon、Circle、Rectangle、Triangle和Square五个对象,由于它们都从Shape派生而来,所以我们可以告诉数组说它们都是一个类型,
    Shape shapes = {new Pentagon(), new Circle(), new Rectangle(), new Triangle(), new Square()};
    你看它们真正做到了求大同存小异,求Shape之大同,存自己形状之小异。没有多态,这些对象就不会在Shape的大同下走到一起。你说多态好不好?
    多态的另一个好处是可以做到抽象编程,也就是说面向接口编程而不是面向实现编程,以应对各种变化。可能这“另一个好处”和“抽象编程”一样“抽象”,楼主继续看书吧。
      

  6.   

    对不起,上边的内拥有错误,重发一次。这个问题再怎么抽象地讲也是云山雾罩,不如做个试验一目了然。假定你的Shape类中有一个构造函数,有一个draw方法,如下:
    class Shape {
           public Shape() {
                 System.out.println("在Shape的构造函数中。");
           }
           public void draw() {
                 System.out.println("Shape类的draw方法。");
           }
    }
    下面这个Pentagon继承了Shape类
    class Pentagon extends Shape{
           public Pentagon () {
                 System.out.println("在Pentagon 的构造函数中。");
           }
           public void draw() {
                 System.out.println("Pentagon 类的draw方法。");
           }
           public void paint() {
                 System.out.println("Pentagon 类的paint方法。");
           }
    }到现在为止,我们有两个类,Pentagon继承Shape,两个类都有一个构造函数和一个draw()方法,Pentagon还有一个Shape没有的方法paint();到现在为止,我们可以静态地看到它们的共同点和不同点,是吧?
    好,现在把它们放到程序中去运行,看看它们的表现。
    public class Poly {
          public static void main(String[] args) {
                    Shape obj = new Pentagon();
                    obj.draw();
          }编译运行,结果为:
    在Shape的构造函数中。
    在Pentagon 的构造函数中。
    Pentagon 类的draw方法。现在对照结果回答楼主的问题:
    1。该对像的实际实现是pentagon的(类):没错,因为obj调用的是Pentagon的draw方法,所以obj实现的Pentagon类
    2。可以认为对像为shape类型,并且具有对pentagon类型的引用:为了印证这句话,现在我们在main方法中加上obj.paint();再编译,咦,程序报错,说找不到paint方法。为什么?
    就是因为obj是Shape类型,而Shape类中并没有paint()方法。关于“具有对pentagon类型的引用”,就不讲了,估计越讲越乱。但到此为止,我们至少明白了两点,1。obj是Pentagon类型因为当调用draw方法时他调用的是Pentagon的draw方法;2。obj是Shape类型因为它不认Pentagon特有的paint方法。换句话说obj兼有Shape和Pentagon两个类的共同点。
    现在回答楼主的第三个问题:
    3。那多态到底有什么好处啊?首先,好处是大大地。我们知道数组可以很方便的定义一系列数据而不必一个一个定义,但有一个缺点,就是每个数组成员的类型必须一样。但有时我们确实需要这样的数组,怎么办,有了多态,问题就好办了。比如,我们有Pentagon、Circle、Rectangle、Triangle和Square五个对象,由于它们都从Shape派生而来,所以我们可以告诉数组说它们都是一个类型,
    Shape[] shapes = {new Pentagon(), new Circle(), new Rectangle(), new Triangle(), new Square()};
    你看它们真正做到了求大同存小异,求Shape之大同,存自己形状之小异。没有多态,这些对象就不会在Shape的大同下走到一起。你说多态好不好?
    多态的另一个好处是可以做到抽象编程,也就是说面向接口编程而不是面向实现编程,以应对各种变化。可能这“另一个好处”和“抽象编程”一样“抽象”,楼主继续看书吧。
      

  7.   

    大家看看我这么理解对不对?
    Shape obj = new Pentagon();  
    obj实际只能调用shape类里的方法和属性
    可是如果在pentagon类里有和shape类里同名的方法
    就会自动调用pentagon类里的方法
    可以调用shape类里的所有方法
    而如果pentagon类里有shape类里没有的方法 就不可以调用 
    这样对不
      

  8.   

    多态是Java中的一个非常好的特性,利用多态非常容易实现通用性的动作(即方法)。
      

  9.   

    可是如果在pentagon类里有和shape类里同名的方法,就会自动调用pentagon类里的方法
    这句话是不对的,只有父类与子类方法名相同,参数也相同才可以。
      

  10.   

    我其实也不知道它具体的实现过程,但我知道它的目的,我就简单说吧,
    多态的目的就是为能用一个统一的接口去实现(驱动)不同的实现(各个实现这个接口的类的处理函数,这个处理函数就是接口里声明但没给出具体代码的那个函数,即名称一样),就好象用一个标准的三角插座就可给任何电器供电一样。
        假设我们定义一个接口“供电系统”,“供电系统”里声明了一个方法“三角插座()”,那么实现这个接口(可理解为遵循此接口协议,就好象各电器厂商都遵守国际插座标准尺寸一样)的各种类(各类电器)就可以都只用这种统一化的"三角插座()"就行了。往后当我们设计到一个想用电的类时,就可直接去调用这个三角插座(),而且要注意的是任何实现(遵循)此接口的类都可以调用相同的“三角插座()”这个接口。
        说到此你可能觉得这个道理其实你也明白,主要是不明白于为什么java要那么做?这还得从人类这个东西说起,你要知道这世界是以人类为主的,当然什么事都要以人为本了,人类是惰性的动物,什么都图方便,发明多态也是,你先别管它那些污七八糟的概念,其目的就是为模仿现实生活的,简单说就是标准化,说穿了也还是为了方便,总之我们生活处处是标准,目的也就想处处方便。回到编程领域也是,多态就是为达到用一个统一的动作来达到驱动多种机器的目的,就好象一个标准的三角插座就可驱动所有遵守此插座协议的电器一样,这就是目的,那么回到手段就是编译器的事了,java采用了独立化的接口的方式,这也不过是java实现以上目的的手段而已,你别追究它为什么这样,这是它的方式,你就管记住那段几乎是固定化的实现接口的代码块。
    重申一次:弄清它的目的,别管它用什么手段,把它背下来得了。
      

  11.   

    dunai2003(马尔罗尼) ( ) 信誉:100    Blog   加为好友  2007-05-02 03:13:10  得分: 0  
    说的好呀 
    这对我们初学者来说是一个大问题呀
    看了你的解释我有点头绪了~