黑马程序员技术交流社区

标题: 分享一道面试题,排错 [打印本页]

作者: 到处玩的    时间: 2014-8-8 23:32
标题: 分享一道面试题,排错
本帖最后由 到处玩的 于 2014-8-9 11:15 编辑

interface Playable {
void play();
}
interface Bounceable {
void play();
}
interface Rollable extends Playable, Bounceable {
Ball ball = new Ball("PingPang");
}
class Ball implements Rollable {
private String name;
public String getName() {
return name;
}
public Ball(String name) {
this.name = name;
}
public void play() {
ball = new Ball("Football");
System.out.println(ball.getName());
}
}

作者: zhangxun    时间: 2014-8-8 23:40
没有main方法,并且ball = new Ball("Football");创建对象时候没有类名是ball,
作者: 烟海    时间: 2014-8-8 23:57
没有main函数。。。
而且在main函数里面,应该重写:Ball ball = new Ball("PingPang"); 这个方法。。。。
这个方法,和void play() 方法应该是并列的。。。所以不应该把ball放到play方法里面。。。应该是并列的两个方法。。
同时接口中的两个都是抽象方法,应该加上abstract方法吧 ??
作者: 790324255a    时间: 2014-8-9 00:16
ball = new Ball("Football"); 接口中成员变量是final修饰 表明该值不可以更改 所以无法通过编译
作者: 舍我其谁    时间: 2014-8-9 00:42
没有main方法先不说,接口中的所有的成员变量都是用 public static final 所修饰的 而这句代码ball = new Ball("Football"); 又从新赋值给ball 所以不可能编译通过的
作者: alvinbx    时间: 2014-8-9 00:55
程序唯一的问题是Ball类里面的play()方法在创建对象是没有声明对象的类型,应该把ball = new Ball("Football")改为Ball ball = new Ball("Football");另外,如果有需要要运行程序的话,少了一个程序入口,即少了一个main方法。可以另外建一个类写个main方法创建Ball对象再调用其play()方法。或者直接在Ball里把play()方法写进main方法里。但是根据题意,并没要求运行,所以没有main方法不算有错。我刚才建了些题目的工程的,运行出来了,结果打印的是Football。不会有错的。很晚了,睡觉了。GOOD NIGHT!
作者: 到处玩的    时间: 2014-8-9 11:15
问题出在interface Rollable里的"Ball ball = new Ball("PingPang");"。任何在interface里声明的interface variable (接口变量,也可称成员变量),默认为public static final。也就是说"Ball ball = new Ball("PingPang");"实际上是"public static final Ball ball = new Ball("PingPang");"。在Ball类的Play()方法中,"ball = new Ball("Football");"改变了ball的reference,而这里的ball来自Rollable interface,Rollable interface里的ball是public static final的,final的object是不能被改变reference的。因此编译器将在"ball = new Ball("Football");"这里显示有错。
作者: /aiq玩完?/aiq    时间: 2014-8-9 23:12
接口中的所有的成员变量都是final的,已经是常量就不能赋值。细节决定成败啊,自己以后做题也要注意了:lol
作者: 王飞163    时间: 2014-8-9 23:56
学习中!!!
作者: inception    时间: 2014-8-10 00:07
收藏,。。。
作者: 刘小印    时间: 2014-8-10 10:45
790324255a 发表于 2014-8-9 00:16
ball = new Ball("Football"); 接口中成员变量是final修饰 表明该值不可以更改 所以无法通过编译 ...

其实主要是靠这个的,不过那些默认的建议还是写上,说不定你自己就忘记了,强烈建议
作者: jwx555    时间: 2014-8-10 11:10
本帖最后由 jwx555 于 2014-8-10 11:12 编辑

1.继承了两个接口,只实现了一个方法
2.接口定义的变量不能再被赋值
作者: 790324255a    时间: 2014-8-10 12:59
刘小印 发表于 2014-8-10 10:45
其实主要是靠这个的,不过那些默认的建议还是写上,说不定你自己就忘记了,强烈建议 ...

          嗯
作者: 严旭晟    时间: 2014-8-10 14:17
一、两个不同的接口拥有相同的方法:public abstract play(),其子接口Rollable继承Playable,Bounceable两个接口时,就获得了两个并列的public abstract play(),而实现该Rollable接口的类就应该实现该接口的所有方法,重写这两个方法时无法确定到底实现了那个接口的方法,而这里只实现了其中的一个(甚至不知道是哪一个)play()方法,因此在设计上建议使用匿名内部类
二、在Rollable接口中定义了一个静态常量,设计的本义是不希望改变,但是在实现该接口的类中,却试图采用“继承”的形式修改该常量的引用!
三、综上,最重要的错误其实是设计上的错误:接口和类、方法重写之间的关系没有真正理清楚!
见下图,红色字体为出错的地方!
作者: 严旭晟    时间: 2014-8-10 14:24
图解示意图

TestInter.jpg (1.46 MB, 下载次数: 20)

TestInter.jpg

作者: 严旭晟    时间: 2014-8-10 15:16
  1. public abstract class Roll implements Bounceable, Playable {
  2.     Ball2 ball ;
  3. }
  4. class Ball2 extends Roll{
  5. private String name;
  6.        
  7.         public String getName(){
  8.                 return name;
  9.         }
  10.         public Ball2(String name){
  11.                 this.name = name;
  12.         }
  13.         @Override
  14.         public void Play() {
  15.                 // TODO Auto-generated method stub
  16.                 ball = new Ball2("Football");
  17.                 System.out.println("Playable: "+ball.getName());
  18.         }
  19.     /*
  20.      * 用匿名内部类的形式*/
  21.         private Bounceable ba = new Bounceable()
  22.         {
  23.                 @Override
  24.                 public void Play() {
  25.                         System.out.println("Bounced Ball: "+Ball2.this.name);
  26.                 }
  27.         };

  28.         public Bounceable getBounceable()
  29.         {
  30.                 return ba;
  31.         }
  32. }
复制代码
将Rollable接口改为抽象类,其中只声明ball;




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2