Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以在Java中为带有接口成员变量的类编写复制构造函数?_Java_Interface_Copy Constructor_Member Variables - Fatal编程技术网

是否可以在Java中为带有接口成员变量的类编写复制构造函数?

是否可以在Java中为带有接口成员变量的类编写复制构造函数?,java,interface,copy-constructor,member-variables,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){

如何为具有接口成员变量的类编写副本构造函数

例如:

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

我是不是被迫要一个具体的
动物
?如果是这样的话,那么将这个类重新用于养狗的房子和养猫的房子似乎变得很复杂

据我所知,在Java中没有与之直接等价的东西

“正确”的方法是使接口自行实现

最简单的方法可能是使用反射。我知道有一个库可以处理任意对象的深度副本,但我现在记不起它的名字了


相关:

如果我理解您的问题,因为您不能在接口中指定构造函数,所以您需要在接口中声明一个深度复制方法,并在类中实现它。不能实例化接口。根据您的需要,您可能还希望深入复制
房屋中的任何内容

public interface IAnimal {
    ...
    IAnimal deepCopy(); 
}


public House(House houseIn){
    this.pet = houseIn.pet.deepCopy();
}

当然,问题是,这取决于你如何让自己不做错事。这有点像你并不真的想要一个接口,而是一个抽象类

好的,让我解释一下代码中的一个问题。请注意,当您有一个界面时,您定义的是一种行为,而不是对象(或生物)的抽象或身份,例如动物。在这种情况下,您需要一个抽象类而不是接口。 贝京说。接口上不能有构造函数(请参阅),因此使用这种方式的接口将失败

因此,在这种情况下,我建议使用抽象类:

public class House {

AbstractAnimal pet;

public House(AbstractAnimal pet) {
    this.pet = pet;
}

public House(House houseIn) {
    this.pet = new AbstractAnimal(houseIn.pet) {
        //implement the abstract methods that are required for anonymous class
    };
}

private abstract class AbstractAnimal {
    //Abstract class attributes 

    public AbstractAnimal(AbstractAnimal Parent) {
        //Constructor code, can also call abstract methods if required
    }
    //declare Abstract methods if required.
}

您有三种选择之一:

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

    对于#1,执行以下操作:

    public interface IAnimal {
        IAnimal cloneDeep();
    }
    
    在具体类型中实现,然后调用该方法复制它:

    this.pet = pet.cloneDeep();
    
    然后将需求记录在界面中,并按照以下内容进行说明:

    此接口的实现必须将一个非
    =
    的对象返回到此实例,并且必须进行深度克隆,以便对该对象的操作不会导致对返回对象的操作,反之亦然

    实现必须遵循此约定才能与接口兼容,但这不会在编译时强制执行

    复制构造函数

    尝试以反射方式访问副本构造函数,然后声明在接口中的所有具体实现中都需要副本构造函数,这将成为接口契约的一部分。每个实现将如下所示:

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

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

    如果需要深度复制,还应在Animal中实现复制构造函数。不能简单地在Animal中实现复制构造函数。在本例中,您有一个接口IAnimal。因此,您需要知道需要实例化哪个具体类。
    Cloneable
    在很多方面都有缺陷,在
    effectivejava
    中,Josh Bloch建议不要使用它。如果你没有那本书,你应该。见:
    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());
    }