简体   繁体   English

在Java接口中使用具有多态性的Clone()

[英]Using Clone() with polymorphism from interface in java

I am having problems trying to figure out how to call the clone method from a object which its reference is of an interface type. 我在尝试弄清楚如何从其引用为接口类型的对象中调用克隆方法时遇到问题。

Basically this is what I need to do. 基本上,这就是我需要做的。

for(Interface obj: objs)
array.add(obj.clone());

I do not know what is the obj type, I just know it implements Interface, and when I try this code I get 我不知道什么是obj类型,我只知道它实现了Interface,当我尝试这段代码时,我得到了

"The method clone() is undefined for the type Interface". “接口类型的方法clone()未定义”。

And when I try to put clone() on my Interface I get: 当我尝试将clone()放在接口上时,我得到:

"The method clone() of type Interface must override or implement a supertype method", because I am using @Override tag. “类型为Interface的方法clone()必须重写或实现超类型方法”,因为我正在使用@Override标记。

My intention is to use Object.clone() in the end. 我的意图是最后使用Object.clone()。 But I just cant figure this out. 但我只是想不通。

Any thoughts? 有什么想法吗?

The real code: 真实代码:

 public interface Caracteristica {
    @Override <---problem
public Object clone() throws CloneNotSupportedException;

    @Override <---fine
public boolean equals(Object obj);
 }

 private final void setCaracteristicas(ArrayList<Caracteristica> caracteristicas) {
    this.caracteristicas = new ArrayList<>();

    for(Caracteristica caracteristica: caracteristicas)
        this.caracteristicas.add((Caracteristica)caracteristica.clone());
 }

Basically, clone() and the Cloneable interface is broken in a number of ways and even according to Josh Bloch it should be avoided. 基本上, clone()Cloneable接口以多种方式破坏,甚至根据Josh Bloch的说法,也应避免这种情况。 (See: http://www.artima.com/intv/bloch13.html ) (请参阅: http : //www.artima.com/intv/bloch13.html

Add a new method to your interface that returns the interface type and implement that in your class to make copies. 向您的接口添加一个新方法,该方法返回接口类型,并在您的类中实现该方法以进行复制。

Edit to Add: Ignoring the above statement, the reason it is telling you that the @Override annotation in your interface is incorrect is because ... it is. 编辑添加:忽略上面的语句,之所以告诉您界面中的@Override批注不正确是因为...是。 You're not extending an interface that defines clone() . 您没有扩展定义clone()的接口。

Interfaces don't extend Object ; 接口不扩展Object ; Section 9.2 of the JLS tells us: JLS的9.2节告诉我们:

If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface. 如果接口没有直接的超接口,则该接口隐式声明带有签名s的公共抽象成员方法m,返回类型r,并引发与每个带有签名s的公共实例方法m,返回类型r和throws子句t对应的子句t在Object中声明,除非接口显式声明了具有相同签名,相同返回类型和兼容throws子句的方法。

clone() is protected in Object so it is not implicitly included. clone()Object protected ,因此不被隐式包含。 If your IDE said to add the @Override tag, report that as a bug, because it's wrong. 如果您的IDE说要添加@Override标记,请将该错误报告为错误,因为它是错误的。

equals() , on the other hand, is public in Object , therefore it is included in the implicit superinterface unless you override it. 另一方面, equals()Objectpublic的,因此除非您重写它,否则它将包含在隐式超级接口中。

If you are bound and determined, this will work though it's really ugly due to the confusion created by clone() being defined both in Object and MyInterface and having it return the interface type (which is allowed because it's a covariant type): 如果你一定和决心,这将工作,但它真的很丑陋由于造成的混乱clone()无论是在被定义ObjectMyInterface ,并让它返回接口类型(这是允许的,因为它是一个协变型):

public interface MyInterface {
    MyInterface clone();
    void doSomething();
}

public class MyClass implements MyInterface {

    @Override
    public void doSomething() {
        System.out.println("Hi");
    }

    @Override
    public MyInterface clone() {
        return new MyClass();
    }

    public static void main(String[] args) {
        MyInterface mi = new MyClass();
        MyInterface mi2 = mi.clone();
        mi2.doSomething();
    }

}

Object.clone() is protected , you can't call it from outside the class or its subclasses unless they explicitly change the access modifier to public thus there is no guarantee an object has a visible clone() method. Object.clone() protected ,您不能从类或其子类外部调用它,除非它们将访问修饰符显式更改为public因此不能保证对象具有可见的clone()方法。

You have to define this in an interface or override it in a baseclass instead. 您必须在接口中定义它,或者在基类中覆盖它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM