Java:为什么为继承设计的类应该包含受保护的克隆方法?
我正在仔细阅读Joshua Bloch的《高效Java》,我发现了以下关于克隆的句子: 如果为继承设计类,请注意,如果选择不提供行为良好的受保护克隆方法,子类将无法实现可克隆性 我有点困惑,因为在我的小测试中:Java:为什么为继承设计的类应该包含受保护的克隆方法?,java,cloning,effective-java,Java,Cloning,Effective Java,我正在仔细阅读Joshua Bloch的《高效Java》,我发现了以下关于克隆的句子: 如果为继承设计类,请注意,如果选择不提供行为良好的受保护克隆方法,子类将无法实现可克隆性 我有点困惑,因为在我的小测试中: public class Cloning { public static void main(String[] args) throws CloneNotSupportedException { Woman woman1 = new Woman("Marie
public class Cloning {
public static void main(String[] args) throws CloneNotSupportedException {
Woman woman1 = new Woman("Marie Curie-Sklodowska", 33, "Physics");
Woman woman2 = (Woman) woman1.clone();
}
static abstract class Person {
protected String name;
protected int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
static class Woman extends Person implements Cloneable {
private String field;
Woman(String name, int age, String field) {
super(name, age);
this.field = field;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
}
我没有得到任何错误。我想,我没有正确理解这个句子。有人能解释一下作者的想法吗
如果为继承设计类,请注意,如果选择不提供行为良好的受保护的clone()
方法,子类将无法实现Cloneable
他错了。他们可以。考虑:
public class A
{
private int fieldA;
}
public class B extends A implements Cloneable
{
public B clone() throws CloneNotSupportedException
{
return (B)super.clone();
}
}
B.clone
()将返回调用它的B
实例的完美副本,包括a.fieldA
。反例反驳:QED
[我知道这个clone()
实际上不应该声明为抛出CloneNotSupportedException
,但它使演示更简单。]
这一切都很奇怪,因为他刚才说了两句话:
有些程序员只是选择从不重写clone()
方法
及
为继承而设计的类不应实现它[Cloneable
]
更奇怪的是,上面的第一句话是整个章节的最后一句话,完全没有论据或例子的支持,除非整个章节都是为了证明这一点,而事实并非如此。整个章节都很混乱,很难弄清楚到底是什么在索赔。克隆并不像他说的那么难理解或实现。这也不重要。在Java的20年里,我没有在严肃的代码中使用过它,也没有在所谓的“复制构造函数”中使用过它
如果为继承设计类,请注意,如果选择不提供行为良好的受保护的clone()
方法,子类将无法实现Cloneable
他错了。他们可以。考虑:
public class A
{
private int fieldA;
}
public class B extends A implements Cloneable
{
public B clone() throws CloneNotSupportedException
{
return (B)super.clone();
}
}
B.clone
()将返回调用它的B
实例的完美副本,包括a.fieldA
。反例反驳:QED
[我知道这个clone()
实际上不应该声明为抛出CloneNotSupportedException
,但它使演示更简单。]
这一切都很奇怪,因为他刚才说了两句话:
有些程序员只是选择从不重写clone()
方法
及
为继承而设计的类不应实现它[Cloneable
]
更奇怪的是,上面的第一句话是整个章节的最后一句话,完全没有论据或例子的支持,除非整个章节都是为了证明这一点,而事实并非如此。整个章节都很混乱,很难弄清楚到底是什么在索赔。克隆并不像他说的那么难理解或实现。这也不重要。在Java的20年里,我没有在严肃的代码中使用过它,也没有在所谓的“复制构造函数”中使用过它。重写
Person.clone()
并使其显式抛出CloneNotSupportedException
。然后它就不起作用了。@AndyTurner这听起来更像是选择提供一个行为不端的clone
方法。@AndyTurner这个问题显然是重复的,但我根本没有得到答案。据我所知,clone()
可以很好地处理超类中的私有字段。嗯,我正在阅读关于同一主题的文章,但我也不清楚接受的答案。它说,创建私有字段“违背了承诺”,但我尝试过使用私有字段,但没有任何区别。克隆的对象是相同的。因此,我的问题可能是克隆,但原始问题没有令人满意的答案。我重新打开该问题,因为我不相信答案令人满意。重写Person.clone()
,并使其显式抛出CloneNotSupportedException
。然后它就不起作用了。@AndyTurner这听起来更像是选择提供一个行为不端的clone
方法。@AndyTurner这个问题显然是重复的,但我根本没有得到答案。据我所知,clone()
可以很好地处理超类中的私有字段。嗯,我正在阅读关于同一主题的文章,但我也不清楚接受的答案。它说,创建私有字段“违背了承诺”,但我尝试过使用私有字段,但没有任何区别。克隆的对象是相同的。因此,我的问题可能是克隆,但原始的问题没有令人满意的答案。我重新打开这个问题,因为我认为答案不令人满意。我原以为克隆部分的摘要有问题。但我认为它达到了它的目标——我对使用clone()
方法和Cloneable
界面感到非常气馁。谢谢你的回答!我原以为克隆部分的摘要有问题。但我认为它达到了它的目标——我对使用clone()
方法和Cloneable
界面感到非常气馁。谢谢你的回答!