che*_*erd 9 java interface copy-constructor member-variables
如何为具有接口成员变量的类编写复制构造函数?
例如:
public class House{
// IAnimal is an interface
IAnimal pet;
public House(IAnimal pet){
this.pet = pet;
}
// my (non-working) attempt at a copy constructor
public House(House houseIn){
// The following line doesn't work because IAnimal (an interface) doesn't
// have a copy constructor
this.pet = new IAnimal(houseIn.pet);
}
}
Run Code Online (Sandbox Code Playgroud)
我被迫有一个混凝土Animal吗?如果是这样的话,似乎重复使用课程与狗的房子与猫的房子变得错综复杂!
您有三种选择之一:
IAnimal可以深度克隆对象(由像DOM这样的库使用Node.cloneNode(boolean))IAnimal它采用具体类型并在接口契约中作为需求,然后使用反射来访问它Serializable类等,像列出的在这里复制方法
对于#1,执行以下操作:
public interface IAnimal {
IAnimal cloneDeep();
}
Run Code Online (Sandbox Code Playgroud)
在您的具体类型中实现它,然后调用该方法来复制它:
this.pet = pet.cloneDeep();
Run Code Online (Sandbox Code Playgroud)
然后在界面中记录需求,说出以下内容:
此接口的实现必须返回不
==属于此实例的对象,并且必须进行深度克隆,以便操作此对象不会导致操作返回的对象,反之亦然.
实现必须遵循此合同才能符合接口,但这不会在编译时强制执行.
复制构造函数
尝试反复访问复制构造函数,然后声明在接口的所有具体实现中都需要复制构造函数,这将成为接口契约的一部分.每个实现将如下所示:
public class Dog implements IAnimal {
private String name;
public Dog(Dog dog) {
this.name = dog.name;
}
}
Run Code Online (Sandbox Code Playgroud)
然后您只需要一个方法来复制每个实现:
public static <A extends IAnimal> A copy(A animal) {
Class<?> animalType = animal.getClass();
// This next line throws a number of checked exceptions you need to catch
return (A) animalType.getConstructor(animalType).newInstance(animal);
}
Run Code Online (Sandbox Code Playgroud)
你有这个,在你的界面文档中添加一个声明:
此接口的实现必须定义一个复制构造函数,该构造函数接受其类的相同类型或超类型的参数.此构造函数必须对参数进行深层复制,以便操作此对象不会导致操作返回的对象,反之亦然.
同样,这是运行时强制执行的.当构造函数不存在时,copy上面的方法会抛出NoSuchMethodException错误.
复制工厂
这需要IAnimal和instanceof用来决定将它传递给哪个方法,例如:
public static IAnimal copyAnimal(IAnimal animal) {
if (animal instanceof Dog)
return copyDog((Dog) animal);
if (animal instanceof Cat)
return copyCat((Cat) animal);
//...
else
throw new IllegalArgumentException("Could not copy animal of type: "
+ animal.getClass().getName());
}
Run Code Online (Sandbox Code Playgroud)
然后copy手动对每种类型的方法进行深度复制.