Java 泛型,接口难题,像这样声明接口有什么好处?

Java 泛型,接口难题,像这样声明接口有什么好处?,java,generics,interface,Java,Generics,Interface,在我的项目中,我看到这样的界面。所有模型都扩展了接口。我想知道这有什么用 public interface IModel { <T> T modelTo(Class<T> clazz); } public interface IPerson extends IModel { public String getFirstName(); public void setFirstName(String firstName); publ

在我的项目中,我看到这样的界面。所有模型都扩展了接口。我想知道这有什么用

public interface IModel {

     <T> T modelTo(Class<T> clazz);
}

public interface IPerson extends IModel {

    public String getFirstName();

    public void setFirstName(String firstName);

    public String getMiddleName();

    public void setMiddleName(String middleName);

}

你能给我解释一下它的含义吗?

我想你会问为什么要使用方法签名

<T> T modelTo(Class<T> clazz);
T模型(类clazz);
使用

参数
clazz
用于实现方法内部的类型信息。然后,您可以非常轻松地访问类型信息

然后,您可以创建一个对象,并从具有给定类的实现方法返回它


方法签名看起来有点笨拙,但很有帮助,因为编译(类型擦除)后缺少泛型信息,并且参数使您能够访问类型信息(以及预期的返回类型)。

我想您会问为什么要使用方法签名

<T> T modelTo(Class<T> clazz);
T模型(类clazz);
使用

参数
clazz
用于实现方法内部的类型信息。然后,您可以非常轻松地访问类型信息

然后,您可以创建一个对象,并从具有给定类的实现方法返回它


方法签名看起来有点笨拙,但很有用,因为编译(类型擦除)后缺少泛型信息,并且参数使您可以访问类型信息(以及预期的返回类型).

我可以想象,通过将Class对象作为调用modelTo(Class clazz)方法的其他方法的参数传递,或者换句话说:让其他方法将IModel对象投射到任何类,而不知道它们将投射到哪个类中,从而允许类型投射(甚至没有什么可以阻止向这个方法传递一个类实例,这个方法甚至不是IModel的子类型…)


了解这个modelTo方法是如何实现的很有意思。抽象骨架类中是否有一个单一的最终实现?它如何响应错误(例如将null作为clazz参数传递,或触发ClassCastException)换句话说:这是不是试图将所有类强制转换封装到一个方法中,用自定义异常或类似的东西替换ClassCastException?(ClassCastException是一个RuntimeException,它可能是一种确保抛出已检查异常的方法,而不是在代码中的任何地方强制执行显式异常处理,我已经看到使用这种方法的项目…)

我可以想象,通过将Class对象作为调用modelTo(Class clazz)方法的其他方法的参数传递,或者换句话说:让其他方法将IModel对象投射到任何类,而不知道它们将投射到哪个类中,从而允许类型投射(甚至没有什么可以阻止向这个方法传递一个类实例,这个方法甚至不是IModel的子类型…)


了解这个modelTo方法是如何实现的很有意思。抽象骨架类中是否有一个单一的最终实现?它如何响应错误(例如将null作为clazz参数传递,或触发ClassCastException)换句话说:这是不是试图将所有类强制转换封装到一个方法中,用自定义异常或类似的东西替换ClassCastException?(ClassCastException是一个RuntimeException,它可能是一种确保抛出已检查异常的方法,而不是在代码中的任何地方强制执行显式异常处理,我已经看到使用这种方法的项目…

它看起来像是在使用。其思想是创建一个“视图”一个类被赋予另一个类,或使一个类成为另一个类

一个简单的现实世界的例子就是电插座。在不同的国家,使用不同类型的插座。因此,您使用适配器将手机插入通常无法“识别”的电插座

当然,也可以使用面向对象编程和适配器模式对其进行建模。使用IModel接口,但命名为IAdaptable,可以这样使用

public interface IAdaptable {
    <T> T adaptAs(Class<T> clazz);
}
public interface IChargeAmerican { void chargePhoneInAmerica(); }
public interface IChargeEurope { void chargePhoneInEurope(); }

public class EuropeanSocket implements IAdaptable, IChargeEurope {
    public <T> T adaptAs(Class<T> clazz) {
        if (clazz.equals(IChargeAmerican.class)) {
            return new EuropeanSocketToAmericanSocketAdapter(this);
        }
        throw new RuntimeException("unknown");
    }

    public void chargePhoneInEurope() {
        ;
    }
}

public class AmericanSocket implements IChargeAmerican {
    public void chargePhoneInAmerica() {
         ;
    }
}

public class EuropeanSocketToAmericanSocketAdapter implements IChargeAmerican {
    private EuropeanSocket socket;
    public EuropeanSocketToAmericanSocketAdapter(EuropeanSocket socket) {
         this.socket = socket;
    }

    public void chargePhoneInAmerica() {
         socket.chargePhoneInEurope();
    }
}
此示例显示Adaptes方法如何在两个接口IChargeAmerican和IChargeEurope之间创建链接。即使它们没有任何共同点,适配器也可以像它们一样工作


现在,EuropeanSocket实现了IAdaptable接口,以便将自身“转换”为另一个已知的套接字。通常情况下,该类不应对此负责。正如wikipedia上的示例所示,工厂或提供商更适合这样做。

它看起来像是使用了。其思想是创建一个“视图”一个类被赋予另一个类,或使一个类成为另一个类

一个简单的现实世界的例子就是电插座。在不同的国家,使用不同类型的插座。因此,您使用适配器将手机插入通常无法“识别”的电插座

当然,也可以使用面向对象编程和适配器模式对其进行建模。使用IModel接口,但命名为IAdaptable,可以这样使用

public interface IAdaptable {
    <T> T adaptAs(Class<T> clazz);
}
public interface IChargeAmerican { void chargePhoneInAmerica(); }
public interface IChargeEurope { void chargePhoneInEurope(); }

public class EuropeanSocket implements IAdaptable, IChargeEurope {
    public <T> T adaptAs(Class<T> clazz) {
        if (clazz.equals(IChargeAmerican.class)) {
            return new EuropeanSocketToAmericanSocketAdapter(this);
        }
        throw new RuntimeException("unknown");
    }

    public void chargePhoneInEurope() {
        ;
    }
}

public class AmericanSocket implements IChargeAmerican {
    public void chargePhoneInAmerica() {
         ;
    }
}

public class EuropeanSocketToAmericanSocketAdapter implements IChargeAmerican {
    private EuropeanSocket socket;
    public EuropeanSocketToAmericanSocketAdapter(EuropeanSocket socket) {
         this.socket = socket;
    }

    public void chargePhoneInAmerica() {
         socket.chargePhoneInEurope();
    }
}
此示例显示Adaptes方法如何在两个接口IChargeAmerican和IChargeEurope之间创建链接。即使它们没有任何共同点,适配器也可以像它们一样工作


现在,EuropeanSocket实现IAdaptable接口以“转换”通常情况下,类不应该对此负责。正如维基百科上的示例所示,工厂或提供商更适合这样做。

IModel与代码有什么关系?IModel和IAdaptable之间有什么关联?在编写代码的方式中,IModel的目的并不明确。S对不起,这是一个打字错误。我已经更正了这个问题。
IPerson
应该在吗