Java: почему класс, предназначенный для наследования, должен содержать защищенный метод клонирования?
Я внимательно читаю "Эффективную Java" (Джошуа Блох) и нашел следующее предложение о клонировании:
Если вы разрабатываете класс для наследования, имейте в виду, что если вы решите не предоставлять хорошо защищенный метод клонирования, для подклассов будет невозможно реализовать Cloneable.
Я немного запутался, потому что в моем маленьком тесте:
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();
}
}
}
Я не получаю никакой ошибки. Я думаю, я не правильно понимаю предложение. Может кто-нибудь объяснить, что имел в виду автор?
1 ответ
Если вы разрабатываете класс для наследования, имейте в виду, что если вы решите не предоставлять хорошо защищенный
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
]
Что еще более любопытно, так это то, что первое предложение выше является последним предложением во всем разделе и полностью не поддерживается ни аргументом, ни примером, если только весь раздел не призван это доказать, а это не так. Весь раздел настолько запутан, что трудно точно определить, что именно заявлено. Клонирование не так сложно понять или реализовать, как он делает. И это не важно. Я не использовал его в серьезном коде за 20 лет Java или так называемых "конструкторов копирования".