15

我对在我想要克隆对象的类中覆盖克隆方法感到困惑。

对象类具有受保护的对象方法,并且根据受保护的行为,即当方法受到保护时,只能由类本身、类的子类或与该类位于同一包中的类访问

由于 Java 中的每个类都从 Object 扩展而来,所以它应该有 clone 方法,但我们仍然被迫重写 clone。为什么需要它?

另外,我在某些地方阅读了覆盖克隆对象并将其公开的内容。我想知道,为什么会这样?

欢迎所有答案。

4

5 回答 5

13

由于 Java 中的每个类都从 Object 扩展而来,所以它应该有 clone 方法,但我们仍然被迫重写 clone

不,您不会被迫重写该clone方法。在继承中,当你继承一个类时,你不必重写它的方法。它的修饰符是 public 或 protected 并没有太大的区别。但是,如果您想直接在super类引用上调用方法,则该方法必须是public. 受保护的方法只能通过继承来访问。也就是说,您只能通过subclass引用访问它们。或者,如果您覆盖该方法,您可以通过super关键字访问它们。

话虽如此,您不应该重写clone方法,因为它是broken. 因为,要克隆一个类,你需要实现Cloneable接口。然后你clone的班级改用 class 的方法Object。因为,Cloneableinterface 并没有任何方法用于cloning. 这将是一个更好的选择Copy Constructor

public class A {
   private int data;
   public A() {
   }

   public A(A a) {
      this.data = a.data;
   }
}

有关更多详细信息,我建议阅读Joshua Bloch'sEffective Java 这一章,它涵盖了使用clone方法的所有方面。

有效的 Java - 第 11 条 - 明智地覆盖克隆

于 2012-10-26T18:11:55.737 回答
5

我建议阅读 Joshua Bloch 的Effective Java 2nd edition。它有一个很好的章节讨论克隆。

我不建议这样做。我认为这是 JDK 1.0 的错误。这本书会更清楚地说明这一点。

我建议编写一个复制构造函数来获得你想要的东西:

public class Foo {
    private String name;
    public Foo(String name) { this.name = name; }
    public Foo(Foo f) { this.name = f.name; }  // copy ctor here.
}
于 2012-10-26T18:12:03.727 回答
3

在许多情况下,并不清楚克隆对象应该是什么以及它应该如何表现,所以如果你希望你的类是可克隆的,你必须通过覆盖克隆并使其公开来明确说明。

克隆可能没有意义的情况包括代表某些资源的类,例如网络连接或同步锁。如果可以克隆这些对象,则不清楚克隆应该如何表现。例如,网络连接的克隆是否有自己的 TCP/IP 连接,或者它是否以某种方式使用现有的连接?

于 2012-10-26T18:14:38.560 回答
2

克隆是类中的Protected方法,Object因此您可以在类中访问它。

关于访问——当一个方法被保护时,它只能被类本身、类的子类或与该类在同一个包中的类访问。

我看到一些关于克隆方法的误解

  1. clone()方法protectedObject类内,所以你不能 clone()在类外调用。例如child.clone(),除非您覆盖它并进行访问public
  2. Cloneable是标记接口,如果你不标记类Cloneable,那么你会得到CloneNotSupportedException如果你调用clone()方法
  3. 如果一个类只包含原始字段或对不可变对象的引用,那么通常情况下,返回的对象中super.clone不需要修改任何字段。
  4. 按照惯例,返回的对象应该通过调用super.clone. 如果一个类及其所有类都superclasses (except Object)遵守这个约定,那么x.clone().getClass() == x.getClass().

方法签名如下

@Override
public Object clone() throws CloneNotSupportedException {
    return super.clone();
}

参考 :

  1. 对象#克隆()
  2. 可克隆
于 2012-10-26T18:30:28.147 回答
-1
    Why we do override clone() in cloning process?
    //clone() in Object class is protected
    package java.lang;


    protected native Object clone()
            throws CloneNotSupportedException;

    java.lang is default import in our java applications.

Note: If parent and sub class are both in same package then the methods in parent class are directly accessible. If they are in different package,then in subclass we have to override the parent class methods to use.

    Note:Object class is in java.lang package,we are using it in different package,so we have to override the clone() which is protected in Object class


first we will look into Protected method behavior.here is sample program to understand this
    //this class is in com.anusha.clonetrial
    package com.anusha.clonetrial;

    public class A {

        public A()
        {

        }
        protected void disp1()
        {
            System.out.println("class a");
        }
        protected void disp2()
        {
            System.out.println("class a");
        }
    }
    //below classes are in com.anusha.Test
    package com.anusha.Test;
    import com.anusha.clonetrial.A;


    class AA {


        protected void disp1()
        {
            System.out.println("class aa");
        }

        protected void disp2()
        {
            System.out.println("class aa");
        }
    }

    //class B derived from AA which is present in the same package
    class B extends AA
    {

        void show()
        {


            System.out.println("class b");
        }
    }

    //class C derived from A which is present in the different package

    class C extends A
    {

        @Override
        protected void disp1()
        {
            super.disp1();
        }
        void show()
        { 
            System.out.println("class c");
        }
    }

    package com.anusha.Test;




    public class CloneTest {


        public static void main(String[] args) {
            B b=new B();
            C c=new C();
            b.disp1();
            b.disp2();
            c.disp1();
            c.disp2();//gives error because it is not overridden.


        }

    }
于 2013-09-22T03:42:47.857 回答