Java 通过接口在2个模块之间转换

Java 通过接口在2个模块之间转换,java,Java,假设我有两个通用类型的模块地球/火星。因此,将有EarthPerson、EarthDog和MarsPerson、MarsDog等。它们可以通过实现一个接口相互转换,以确保它们可以相互转换,但仍然保持相同的类型。例如:person只能是person而不是dog public interface Mars<T extends Earth> { T toEarth(); interface Earth<T extends Mars<V>,V extends

假设我有两个通用类型的模块地球/火星。因此,将有EarthPerson、EarthDog和MarsPerson、MarsDog等。它们可以通过实现一个接口相互转换,以确保它们可以相互转换,但仍然保持相同的类型。例如:person只能是person而不是dog

public interface Mars<T extends Earth> {
    T toEarth();
    interface Earth<T extends Mars<V>,V extends Earth>{
        T toMars();
    }
}
公共接口{
T toEarth();
接口接地{
T-toMars();
}
}
不知何故,我认为那些通配符似乎很复杂。但它为我保证了打字的安全性。
所以我的问题是,我该如何重组这一点

您的示例的语义有点笨拙,但您可以通过应用。生成的客户端代码可能如下所示:

@Test
public void testPerson() {
    InterplanetaryTravelling<Person> traveller = new Person();
    assertEquals("", traveller.whereWasI());

    traveller = new ToEarth<>(traveller);
    assertEquals("Earth", traveller.getCurrentPlanet());
    assertEquals("Earth", traveller.whereWasI());

    traveller = new ToMars<>(traveller);
    assertEquals("Mars", traveller.getCurrentPlanet());
    assertEquals("Earth, Mars", traveller.whereWasI());
}

@Test
public void testDog() {
    InterplanetaryTravelling<Dog> traveller = new Shepherd();
    assertEquals("", traveller.whereWasI());
    // ... same as for the person
}

@Test
public void testTypeSafety() {
    InterplanetaryTravelling<Person> traveller = new Shepherd(); // Compiler Error
}
@测试
公众人士(){
星际旅行旅行者=新人();
assertEquals(“,旅行者。我在哪里());
旅行者=新地球(旅行者);
assertEquals(“地球”,traveler.getCurrentPlanet());
assertEquals(“地球”,旅行者,我在哪里?);
Traveler=新的Tomar(Traveler);
assertEquals(“火星”,traveler.getCurrentPlanet());
assertEquals(“地球,火星”,旅行者,whereWasI());
}
@试验
公共无效测试狗(){
星际旅行旅行者=新牧羊人();
assertEquals(“,旅行者。我在哪里());
//…和那个人一样
}
@试验
公共安全(){
星际旅行旅行者=new Shepherd();//编译器错误
}
这是一个有效的解决方案,因为您只实现了一次类型相关的代码。它也是可伸缩的,对于每个新类型,您只需要创建一个新类,而不必为每个可能的类型组合创建类

我的装饰器具有以下实现:

interface InterplanetaryTravelling<T> {
    String getCurrentPlanet();

    String whereWasI();
}

abstract class InterplanetaryTravellingDecorator<S> implements InterplanetaryTravelling<S> {

    private final InterplanetaryTravelling<? extends S> decoratedTraveller;

    InterplanetaryTravellingDecorator(InterplanetaryTravelling<? extends S> traveller) {
        this.decoratedTraveller = traveller;
    }

    @Override
    public String whereWasI() {
        String previousTravels = decoratedTraveller.whereWasI();

        return previousTravels.isEmpty() ? this.getCurrentPlanet()
                : previousTravels + ", " + this.getCurrentPlanet();
    }
}

class ToEarth<S> extends InterplanetaryTravellingDecorator<S> {

    ToEarth(InterplanetaryTravelling<? extends S> person) {
        super(person);
    }

    @Override
    public String getCurrentPlanet() {
        return "Earth";
    }

}

class ToMars<S> extends InterplanetaryTravellingDecorator<S> {

    ToMars(InterplanetaryTravelling<? extends S> person) {
        super(person);
    }

    @Override
    public String getCurrentPlanet() {
        return "Mars";
    }

}

class Person implements InterplanetaryTravelling<Person> {

    @Override
    public String getCurrentPlanet() {
        return "";
    }

    @Override
    public String whereWasI() {
        return "";
    }

}

abstract class Dog implements InterplanetaryTravelling<Dog> {

    @Override
    public String getCurrentPlanet() {
        return "";
    }

    @Override
    public String whereWasI() {
        return "";
    }

}

class Shepherd extends Dog { }
接口行星际旅行{
字符串getCurrentPlanet();
字符串whereWasI();
}
抽象类InternetaryTravelingDecorator实现InternetaryTraveling{

私人最终星际旅行这真的很奇怪。
MarsPerson
为什么会变成
EarthPerson
?如果是火星人,那么就不是地球人。我的观点是,这可能表明你的设计中存在一些错误听起来你更需要一个摘要(?)课程名为Person,然后扩展到MarsPerson/EarthPerson?@ViktorMellgren如果只是关于人和狗,那么可能是的。但是如果你还想处理木星、冥王星和金星上的猫、马和鸟呢?想想你必须创建的所有组合!这不完全是我想要的,但它真的打开了我的心扉。谢谢回答。