interface Sporty {
void beSporty();
}
class Ferrari extends Car implements Sporty {
public void beSporty() {

// implement cool sporty method in a Ferrari-specific way
}
}
class RacingFlats extends AthleticShoe implements Sporty {
public void beSporty() {

// implement cool sporty method in a RacingShoe-specific way
}
}
class GolfClub { }
class TestSportyThings {
public static void main (String [] args) {
Sporty[] sportyThings = new Sporty [3];
sportyThings[0] = new Ferrari(); // OK, Ferrari implements Sporty
sportyThings[1] = new RacingFlats();
// OK, RacingFlats implements Sporty
sportyThings[2] = new GolfClub();我想问一下:
1,定义了接口Sporty, 还可以定义为数组吗?
2, GolfClub 没有implements Sporty过,就不能作为Sporty的书组成员了吗?
3,作为它的数组成员是什么意思呢?有什么意义?

解决方案 »

  1.   

    1. 可以,接口只是不能生成自己的对象.
    2. 这是肯定的,这个就是向上转型,implements你也可以理解为继承,不过是要实现接口中的方法罢了.
    3. 上面已经回答过了,这个就是向上转型.也就是多态.
      

  2.   

    我想回答一下:
    1,定义了接口Sporty, 还可以定义为数组吗?
    看不懂你在问什么
    2, GolfClub 没有implements Sporty过,就不能作为Sporty的书组成员了吗?
    不可以
    3,作为它的数组成员是什么意思呢?有什么意义?
    呵呵,最简单的说可以直接调用beSporty方法,而不必在乎具体是什么类
    复杂一点,说明都是实现了这个接口的类,实现面向抽象编程
      

  3.   

    1。可以
    2。GolfClub不能作为Sporty的数组成员
    3。成为它的数组的成员表示这些成员都是直接或间接实现了Sporty接口,在进行某些操作(例如遍历)时会方便
      

  4.   

    补充:
    1.定义数组又没有生成对象.
    2 .如果没有implements Sporty过,那两个类就没有任何联系,这样的话怎么能将一个类的对象付给另一个类的引用呢?
      

  5.   

    mofeir(损人专家) 第3点的意思是说beSporty方法可能是一个使用的比较多的方法,而这样子写代码的用意就是使beSporty方法能够被很容易的调用到,是吗?
      

  6.   

    如果不用接口Sporty作为数组,向下面这样:
    ABC[] ABCThings = new ABC [3];
    ABCThings0] = new Ferrari(); 
    ABCThings[1] = new RacingFlats();
    ABCThings[2] = new GolfClub();
    我觉得依然不影响Ferrari(); RacingFlats();使用Sporty接口里面的方法beSporty()啊为什么他要在定义数组的时候用接口Sporty呢?
      

  7.   


    你那样写就是错的.除非ABC 为 其他几个的父类.
    这个就是多态的好处,这里体现的不是很明显!可能是你程序不全吧?
    回去翻一下书吧,书上讲的很清楚的.
    多态的好处是更好的代码组织,更好扩展的程序.更容易维护的代码.
    Sporty[] sportyThings = new Sporty [3];
    比如这个,如果有一个方法比如f(Sporty[] b).只有在执行时才知道是那个对象被传递进来.这样的话可以省很多代码,当然这个只是一个很小的方面!
      

  8.   

    关于第三点也不完全是这个意思,其实继承这个接口,就是融入了某一个体系,而这个体系必然在某一概念上存在实际意义。举个简单的例子,interface Shape{ void draw(); }class Rectangle implements Shape {
      void draw() {
        // Draw a rectangle 
      }
    }class Circle implements Shape {
      void draw() {
        // Draw a Circle
      }
    }    在这里,我们都明白在现实生活中,圆与长方形在概念上属于Shape,所以其接口继承了Shape interface,interface则不过是一纸契约,规定了成为Shape体系中的一员将要遵守的行为法则。于是乎,当某一个类一旦继承了Shape,则必然需实现其申明的methods,而且这些methods相对于这些对象拥有概念上几乎相等的意义(但实现则各有不同)。这就是继承的原理。
        楼主在继承的概念上似乎有些走入危险的误区(或者是我的理解产生了误会),面向对象的初学者很容易滥用继承机制(虽然很多初学者也看了许多书,并对那些书上的有关继承的警告加以了解,但大多数人在没有实际编写许多对象的真正程序之前,其实只能知其然而不知其所以然,在下也算是一例)。
        关键在于不要为了代码的复用方便,或是对某个功能敢兴趣而盲目的继承了某个对象或实现了某个接口,只有当在现实当中如此继承在概念上确实有意义时才应该这样去做。毕竟在人类的歌唱与鸟儿的歌唱不属于同一概念,我们对动物的歌唱的理解不过是动物的叫声而已,所以不要因为都是唱歌就把bird继承了human,而只是因为他们都会唱歌(呵呵)。@.@||~
      

  9.   

    midthinker(呵呵)
    想的可能过多了~
    我们只是就这段程序来说当他是麻雀继承了鸟的 唱歌,和人没有关系.
    这点我了解的.
      

  10.   

    为什么是错的,因为Ferrari(); 他们implement接口里的方法吗?那如果没有implement的话,ABC就不一定要是父类了吧.另外省了很多代码是怎么回事,我经验少,能举个例子说吗?你举的这个体现方便的例子我也没看懂.
      

  11.   

    呵呵,多态的最大好处便是让你忘记具体的型别而关注于一类对象的实体概念。还是举shape的例子,
        interface Shape{ void draw(); }    class Rectangle implements Shape {
          void draw() {
            // Draw a rectangle 
          }
        }    class Circle implements Shape {
          void draw() {
            // Draw a Circle
          }
        }
        
        以上不过是静态的继承体系,你可以想象将这样的体系移植到一个画板程序中(哦,我知道这需要些想象力,呵呵),然后由于你可以在画板上画出各种各样的图形,由于图形是可以组合、层叠、交叉,这就使得你的画板(Board)必须维护一份图形(Shape)数组。
        就像这样,Shape[] s = new Shape[3];
        然后,这个数组需要维护当前画板上的各种图形,就像这样将他们存放进去。
        Shape[0] = new Circle();
        Shape[1] = new Rectangle();
        Shape[2] = new Circle();
    当然事实上画板上不只三层的层叠,数组的不一定为3,同样Shape的类型可能更加丰富,这里如此只是为了叙述方便。突然,我们可能需要重绘(repaint)一下这些图形。事实上,这时候对我们来说画板上的是什么样的图形,有多少我们压根不关心,重要的是我们意图将他们依次重新画出来,那么我们可以这样,
        for (int i = 0; i < s.length; i++)
          s[i].draw();
    神奇的是,这些图形自动的依照我们的命令重新绘制了(repaint)他们,我们不必要先知道他们是什么图形,他们会自我处理。但如果我们没有使用多态,那么我们只能:“哦,你是圆吗?奥,好我调用circle.draw();哦,你是长方形吗?奥,好我调用rectangle.draw()...多麻烦的事情”
        至于多态的好处,实在不是一两句话能说清楚的,而且在对象的三个特性中,多态可能是最重要也是最有魅力的一个,楼主可以参看许多优秀的书籍,并从中获得有关知识,但由于多态是一种概念,所以如果不自己动手写出真实的程序前实在是无法理解其实现的意义到底在于何?@.@||~
      

  12.   

    我原来对多态的理解是建于OVERLOAD之上的,不知道是不是谬误?
      

  13.   

    TO:凡凡
        恩...坦率的说,在没有成为真正的老鸟之前真得不敢妄加评述(怕误人子弟,呵呵),不过就我的实际经验来说,对于多态的真正理解还是在于对概念的抽象,就像我刚才所举的例子,我们需要的不过是一组图形,至于图形是什么?在重绘的过程中我们根本不用关心,如果我们使用过程化的语言来编写程序,就不得不动用大量的条件转移语句,如
        if(长方形)
          长方形.draw()
        else if(正方形)
          正方形.draw()
        else if(圆型)
          圆形.draw()
        else if
          ...
    问题会随着概念域的扩大而无限放大(你的图形有多少?又有多少类型的图形可供调用?),当放大到一定的时刻,我们的精力与理解力就不足以维护这样的代码了,而事实是他们在概念上确是完全一样的。
        对象本来就是对一类实体在概念上的抽象与逻辑的组织,所以多态正是将对象的功能放大的最有力武器之一。随便说说,呵呵@.@||~
      

  14.   

    hehe...
        最后非常抱歉于在您的帖子了说了些废话(可能是),请原谅我没有切入正题,我这样做只是因为就我的实际经验告诉我,继承、多态、接口其实都是概念上的问题,很多时候我们对实际应用完全不能理解其实就是对概念无法理解,所以先说明概念可能对理解真正的问题大有好处。
        现在来说明实际的问题,
        sportyThings[2] = new GolfClub();  // 引用子上例代码
        为什么不接口继承自Sporty的GolfClub就无法放入Sporty数组呢?因为他们在概念上完全是两种东西,你不可能将人类放入狮子笼里,并寄希望狮子能与人类和平相处,哈哈。Sporty数组里存放的必须是在概念上就是Sporty的东西,继承了此接口的Class自然就是Sporty家庭体系中的一员,是可以被接受的,但如果没有继承此接口,这两者属于完全不同的范畴,就像人类与狮子,风马牛不相及了,呵呵。@.@||~
      

  15.   

    对于呵呵说的最后一条,我不太理解的是:Sporty是个接口没错;
    以Sporty为名字的数组除了名字和此接口一致,还有什么意义?
    是有接口意义的数组?
    我不理解的是以Sporty为名字的数组为什么一定只能容纳使用Sporty接口的引用,因为除了名字一样以外,我看不出这个接口和数组有什么必然关系.
    我的疑问一句话就是:继承了接口的引用为什么一定要放在和接口同样名字的数组里??
      

  16.   

    你还是没理解,只有implements了Sporty 的类才能放在Sporty[] sportyThings这个数组中.这个就是向上转型.implements也可以理解为继承. 
    你想一下你能将String型的放进int型的数组吗?而这里通过向上转型将父类的引用指向子类的对象.我觉得上面几位解释的已经很清楚了!
      

  17.   

    ^_^,好处? hehe已经解释的比较清楚了!而且上面我也已经解释过了!
      

  18.   

    好处在前面的几帖中已经有过阐述了,最大的好处莫过于对概念的抽象。
        这里恐怕需要大量的实践才能真正理解与体会其带来的好处。不过记住,当你使用诸如JAVA、C++之类的工具开发程序时,我们更多的是为现实的事物在虚拟的电子世界里的模拟,所以我们更加应该关注的是我们要做的事情,而不是怎么做这件事情。
        所以,我们只要知道各种图形画图,至于圆是怎么画图的,椭圆是怎么画图的,长方形是如何画图的,由他们自己去解决吧。@.@||~