Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.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_Clone_Overriding - Fatal编程技术网

Java 为什么需要覆盖对象的克隆方法

Java 为什么需要覆盖对象的克隆方法,java,clone,overriding,Java,Clone,Overriding,java中的每个类都隐式扩展对象类。克隆()在对象中受保护。 受保护的方法对于子类是可见的。那么我们为什么需要重写? 即使我读了很多网站,我也无法理解这些概念。 请解释清楚。 谢谢。您只需要覆盖那些需要自己实现的超类方法。如果您想要超类的默认行为,那么无需重写您只需要重写那些需要自己实现的超类方法。如果您想要超类的默认行为,则无需重写,因为克隆将仅从子类可见。其他类,即使是来自同一软件包的类,也不会在子级中看到克隆,因此无法克隆子级: class Test2 implements Cloneab

java中的每个类都隐式扩展对象类。克隆()在对象中受保护。 受保护的方法对于子类是可见的。那么我们为什么需要重写? 即使我读了很多网站,我也无法理解这些概念。 请解释清楚。
谢谢。

您只需要覆盖那些需要自己实现的超类方法。如果您想要超类的默认行为,那么无需重写

您只需要重写那些需要自己实现的超类方法。如果您想要超类的默认行为,则无需重写,因为克隆将仅从子类可见。其他类,即使是来自同一软件包的类,也不会在子级中看到克隆,因此无法克隆子级:

class Test2 implements Cloneable {
}

public class Test1 {


    public static void main(String[] args) throws Exception {
        Test2 t2 = new Test2();
        t2.clone(); <-- compile time error: Method clone() from type Object is not visible
    }
}
类Test2实现可克隆{
}
公共类Test1{
公共静态void main(字符串[]args)引发异常{
Test2 t2=新的Test2();

t2.clone();这是因为克隆将仅从子类可见。其他类,即使是来自同一包的类,也不会在子类中看到克隆,因此将无法克隆子类:

class Test2 implements Cloneable {
}

public class Test1 {


    public static void main(String[] args) throws Exception {
        Test2 t2 = new Test2();
        t2.clone(); <-- compile time error: Method clone() from type Object is not visible
    }
}
类Test2实现可克隆{
}
公共类Test1{
公共静态void main(字符串[]args)引发异常{
Test2 t2=新的Test2();
t2.clone();让我们一步一步地回顾克隆:

  • 虽然每个对象都继承
    object.clone()
    ,但默认情况下克隆是不启用的。这意味着如果您尝试
    clone()
    某个随机对象,您可能会得到CloneNotSupportedException

  • 要启用克隆,对象的类或其超类之一必须实现Cloneable接口。它只是一个标记接口,如果没有它,将抛出上述异常

  • 假设已启用克隆,则默认实现将继承为受保护的。因此,类仍然可以使用它来创建其对象的副本,但公众还不能调用它

  • 现在,如果您的类希望提供从类外部复制其对象的功能,那么它可以将
    Object.clone()
    重写为public,只需在内部调用
    super.clone()
    ,即可使用默认实现

  • 这就引出了最后一点。默认实现是对对象进行浅层复制,这意味着它只需将所有原语以及引用值复制到新对象上。这意味着,复杂的数据结构,如
    映射
    将得到共享,因为两个副本都有两个不同的引用,但它们将指向相同的
    地图


    这就是为什么覆盖在大多数情况下都必须提供自己的实现来创建(更广为人知的)对象的深度副本,以便克隆不共享其源对象的任何状态,并且可以独立修改而不影响其他对象的状态

让我们一步一步地回顾克隆:

  • 虽然每个对象都继承
    object.clone()
    ,但默认情况下克隆是不启用的。这意味着如果您尝试
    clone()
    某个随机对象,您可能会得到CloneNotSupportedException

  • 要启用克隆,对象的类或其超类之一必须实现Cloneable接口。它只是一个标记接口,如果没有它,将抛出上述异常

  • 假设已启用克隆,则默认实现将继承为受保护的。因此,类仍然可以使用它来创建其对象的副本,但公众还不能调用它

  • 现在,如果您的类希望提供从类外部复制其对象的功能,那么它可以将
    Object.clone()
    重写为public,只需在内部调用
    super.clone()
    ,即可使用默认实现

  • 这就引出了最后一点。默认实现是对对象进行浅层复制,这意味着它只需将所有原语以及引用值复制到新对象上。这意味着,复杂的数据结构,如
    映射
    将得到共享,因为两个副本都有两个不同的引用,但它们将指向相同的
    地图


    这就是为什么覆盖在大多数情况下都必须提供自己的实现来创建(更广为人知的)对象的深度副本,以便克隆不共享其源对象的任何状态,并且可以独立修改而不影响其他对象的状态


如果不需要,则不需要覆盖它:)如果不需要,则不需要覆盖它:)受保护的方法将适用于子类。所有类都在java中扩展对象类。因此,它应该是可见的。知道吗?请参阅我的更新中的示例,每个示例Test2扩展对象(内部)。因此,现在Test2将具有从对象类继承的受保护克隆方法。如果我在Test1类(在同一个包中)中为Test2创建对象,它应该可以访问同一个包中的受保护成员?(Test2具有受保护克隆()方法)。为什么会出现编译错误。不,它仅在类Test1本身可见,同一个包中的类无法看到它。您需要显式添加受保护的克隆()到Test1使其从同一个包中的类可见受保护的方法将适用于子类。所有类都在java中扩展对象类。因此,它应该是可见的。知道吗?请参阅我的更新中的示例,每个示例Test2扩展对象(内部)。因此,现在Test2将具有受保护的克隆方法,该方法继承自