关于对象Casting的疑问

时间:2011-05-18 22:13:22

标签: java

enter image description here

我正在帮助一位朋友从第一年开始准备他的Java考试。 老师要求他们创建一种可以将音乐家投射到诗人的方法。

没有人知道该怎么做。经过一段时间的思考,我得出的结论是,不可能这样做( ClassCastException ),因为Musician和Poet共享一个接口的事实不足以将它们转移到另一个接口上。< / p>

我认为只有在相同的继承链中才有可能。

现在我有三个问题:

  1. 我是对的吗?
  2. 如果我是对的,教授希望他们做什么?我真的怀疑他会要求这样的事情。
  3. 如果我错了,你能编写一个可以将音乐家投入诗人的代码吗?

8 个答案:

答案 0 :(得分:2)

  1. 你是对的
  2. 特技提问?
  3. 不,至少,不是没有ClassCastException
  4. 你可以尝试:

     Musician musician = new Musician();
     Artist artist = musician;
     Poet poet = (Poet)artist;
    

    但是,当然,该代码实际上不会在运行时工作。

答案 1 :(得分:1)

你是对的。根据您的继承结构,您无法将Musician强制转换为Poet

您唯一能做的就是创建一个Poet的外观对象,并将相关的方法调用转发给关联的Musician

答案 2 :(得分:1)

只是为了提出想法......你能使用java.lang.reflect.Proxy类吗?

编辑..

实际上你并不像我提到的那样需要代理。使用我从动态子分类中借鉴的想法,您可以实现将音乐家转换为诗人的目标。基本上你做的是 你必须创建一个扩展Poet的类,在构造函数中接受一个音乐家。然后在子类中,您可以覆盖Poet的每个方法,将Poet的方法“映射”到Musician的方法。

我已经在一个类中编写了所有内容,这不是一个好的编程风格,但它在SO上更容易; - )

public class Caster {

    public static void main(String[] args){
        Musician m = new Musician();

        Caster caster = new Caster();

        Poet p = caster.cast(m);

        System.out.println(p.getPoetryGenre());

    }

    public Poet cast(Musician m){
        Poet p = new PoetWannabe(m);

        return p;
    }

    private class PoetWannabe extends Poet{

        private Musician musicianInDisguise;

        public PoetWannabe(Musician m){
            this.musicianInDisguise = m;
        }

        @Override
        public String getPoetryGenre() {
            return musicianInDisguise.getMusicGenre();
        }

        @Override
        public void setPoetryGenre(String g) {
            musicianInDisguise.setMusicGenre(g);
        }

        /*override more methods as you wish*/
    }

}

答案 3 :(得分:1)

音乐家和诗人都可以成为界面吗?如果是这样的话,可以有一个实现两者的类,可以从音乐家演绎到诗人,反之亦然。

public interface Musician {
  void sing();
}

public interface Poet {
  void read();
}

public class Common implements Musician, Poet {
  public void sing() {
    //sing
  }

  public void read() {
    //read
  }
}


public Musician convert(Poet poet) {
  if(poet instancof Musician) {
    return (Musician) poet;
  else {
    throw new IllegalArgumentException("Not a musician");
  }
}

public void test() {
  Common rapper = new Common();
  Musician singer = convert(rapper);
}

答案 4 :(得分:1)

static Poet musicianToPoet(String fileName) {
    Poet p = new Poet();
    p.readArtist(fileName);  // this method is defined in the interface
    return p;
}

static Poet musicianToPoet(Musician musician) {
    String filename = "/some/file/name.txt";
    musician.saveArtist(filename);
    return musicianToPoet(filename);
}

答案 5 :(得分:0)

public Musician getMusician(Poet p) {
    Artist a = p;
    return (Musician)a;
}

是的,这会因ClassCastException而爆炸。但是,至少从语言层面来看,SEEMS就像它可以做到的那样。但是运行时会在运行时阻止它。

答案 6 :(得分:0)

你是对的,音乐家和诗人是共享相同基础实现的不同类。你唯一能做的就是演员IArtist&lt; - &gt;艺术家&lt; - &gt;音乐家,或者IArtist&lt; - &gt;艺术家&lt; - &gt; Poet

答案 7 :(得分:0)

用你的班级图表。不,你不能把一个音乐家投入诗人。你确定教授不是要求你/你的朋友重新设计课堂树吗?