我正在帮助一位朋友从第一年开始准备他的Java考试。 老师要求他们创建一种可以将音乐家投射到诗人的方法。
没有人知道该怎么做。经过一段时间的思考,我得出的结论是,不可能这样做( ClassCastException ),因为Musician和Poet共享一个接口的事实不足以将它们转移到另一个接口上。< / p>
我认为只有在相同的继承链中才有可能。
现在我有三个问题:
答案 0 :(得分:2)
ClassCastException
。 你可以尝试:
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)
用你的班级图表。不,你不能把一个音乐家投入诗人。你确定教授不是要求你/你的朋友重新设计课堂树吗?