java - 是否可以在 Java 中为具有接口(interface)成员变量的类编写复制构造函数?

标签 java interface copy-constructor member-variables

如何为具有接口(interface)成员变量的类编写复制构造函数?

例如:

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);
    }
}

我是否被迫拥有一个具体的Animal如果是这样,那么将这个类重新用于有狗的房子和有猫的房子似乎变得令人费解!

最佳答案

您有以下三种选择之一:

  1. IAnimal 上有一个方法来深度克隆对象(由诸如 Node.cloneNode(boolean) 之类的 DOM 接口(interface)之类的库使用)
  2. IAnimal 的所有实现中创建一个采用具体类型的复制构造函数,并将其作为接口(interface)契约中的要求,然后使用反射来访问它
  3. 创建一个复制工厂,手动复制每个实现
  4. 使用第 3 方库,它通过自己的契约为您实现深度克隆,例如无参数构造函数、非最终字段、Serializable 类等,例如 here 中列出的那些

复制方法

对于#1,做类似的事情:

public interface IAnimal {
    IAnimal cloneDeep();
}

在您的具体类型中实现它,然后调用该方法来复制它:

this.pet = pet.cloneDeep();

然后在界面中记录需求,大致如下:

Implementations of this interface must return an object that is not == to this instance, and must be deeply cloned so that manipulation of this object does not lead to manipulation of the returned one and vice versa.

为了与接口(interface)兼容,实现必须遵循此约定,但这不会在编译时强制执行。

复制构造函数

尝试以反射方式访问复制构造函数,然后声明在接口(interface)中的所有具体实现中都需要复制构造函数,这成为接口(interface)契约的一部分。每个实现看起来像这样:

public class Dog implements IAnimal {

    private String name;

    public Dog(Dog dog) {
        this.name = dog.name;
    }
}

然后您只需要一个方法来复制每个实现:

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);
}

如果你有这个,在你的界面文档中添加一个声明来实现这个效果:

Implementations of this interface must define a copy constructor that takes an argument of the same type or supertype of their class. This constructor must make a deep copy of the argument so that manipulation of this object does not lead to manipulation of the returned one and vice versa.

同样,这是运行时强制执行的。当构造函数不存在时,上面的 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());
}

然后在 copy 方法中手动对每种类型进行深度复制。

关于java - 是否可以在 Java 中为具有接口(interface)成员变量的类编写复制构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17075621/

相关文章:

java - 无法传输 http ://repo. maven.apache.org/maven2 - 错误代码 501,需要 HTTPS

java - Eclipse Indigo 中的奇怪错误

java - 双重依赖注入(inject)和良好实践

c# - 接口(interface)的隐式和显式实现

c++ - 为什么用户定义的移动构造函数会禁用隐式复制构造函数?

java - php 和 servlet 应用程序之间的通信

go - map[string]interface{} 和 interface{} 的区别

android - Kotlin : Casting an object to Generic class

c++ - 插入指针列表 C++

c++ - array<int,2> dim 在这段代码中是什么意思?