Java 通过接口在2个模块之间转换
假设我有两个通用类型的模块地球/火星。因此,将有EarthPerson、EarthDog和MarsPerson、MarsDog等。它们可以通过实现一个接口相互转换,以确保它们可以相互转换,但仍然保持相同的类型。例如:person只能是person而不是dogJava 通过接口在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
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如果只是关于人和狗,那么可能是的。但是如果你还想处理木星、冥王星和金星上的猫、马和鸟呢?想想你必须创建的所有组合!这不完全是我想要的,但它真的打开了我的心扉。谢谢回答。