File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ package clone ;
2+
3+ /*
4+ * 以下实现的是深拷贝;
5+ * 而Java默认的是浅拷贝,
6+ * 浅拷贝并没有克隆包含在对象中的内部对象;
7+ * 通常来说,使用浅拷贝的情况下,
8+ * 如果原始对象与浅克隆对象共享的子对象是不可变的话,
9+ * 将不会产生任何问题;
10+ * 但更常见的情况是子对象可变,
11+ * 所以必须重新定义clone方法,
12+ * 以便实现克隆子对象的深拷贝
13+ *
14+ * 对于每一个类,都需要做出下列判断:
15+ * 1. 默认的clone方法是否满足需求
16+ * 2. 默认的clone方法是否能够通过调用可变子对象的clone得到修补
17+ * 3. 是否应该不是用clone
18+ * 实际上,选项3是默认的。如果要选择1或2,类必须:
19+ * 1. 实现Cloneabel接口
20+ * 2. 使用public访问修饰符重新定义clone方法
21+ *
22+ * 注意,在Object类中,clone被声明为protected,
23+ * 因此无法直接调用anObject.clone()(参阅《Core Java Volumn I》第五章内容)。
24+ * 子类只能调用受保护的clone方法克隆它自己。
25+ * 为此,必须重新定义clone方法,并将它声明为public,
26+ * 这样才能让所有方法克隆对象
27+ */
28+ public class CloneTest {
29+ public static void main (String [] args ) {
30+ try {
31+ Employee original = new Employee ("John Q. Public" , 50000 );
32+ original .setHireDay (2000 , 1 , 1 );
33+ Employee copy = original .clone ();
34+ copy .raiseSalary (10 );
35+ copy .setHireDay (2002 , 12 , 31 );
36+ System .out .println ("original=" + original );
37+ System .out .println ("copy=" + copy );
38+ }
39+ catch (CloneNotSupportedException e ) {
40+ e .printStackTrace ();
41+ }
42+ }
43+ }
Original file line number Diff line number Diff line change 1+ package clone ;
2+
3+ import java .util .Date ;
4+ import java .util .GregorianCalendar ;
5+
6+ public class Employee implements Cloneable {
7+ private String name ;
8+ private double salary ;
9+ private Date hireDay ;
10+
11+ public Employee (String n , double s ) {
12+ name = n ;
13+ salary = s ;
14+ hireDay = new Date ();
15+ }
16+
17+ public Employee clone () throws CloneNotSupportedException {
18+ Employee cloned = (Employee ) super .clone ();
19+ cloned .hireDay = (Date ) hireDay .clone ();
20+ return cloned ;
21+ }
22+
23+ public void setHireDay (int year , int month , int day ) {
24+ Date newHireDay = new GregorianCalendar (year , month - 1 , day ).getTime ();
25+ hireDay .setTime (newHireDay .getTime ());
26+ }
27+
28+ public void raiseSalary (double byPercent ) {
29+ double raise = salary * byPercent / 100 ;
30+ salary += raise ;
31+ }
32+
33+ public String toString () {
34+ return "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]" ;
35+ }
36+ }
Original file line number Diff line number Diff line change 77 * 为了让类实现一个接口,通常需要下面几个步骤:
88 * 1. 将类声明为实现给定的接口
99 * 2. 让接口中的所有方法进行定义
10+ *
11+ * 在这里讨论一下接口与抽象类之间的区别:
12+ * 但是由于Java只支持单继承,而不是C++那样的多重继承,
13+ * 所以使用抽象类的时候,每个类都只能扩展于一个类;
14+ * 但是却可以实现多个接口,
15+ * 接口可以提供多重继承的大多数好处,
16+ * 同时还能避免多重继承的复杂性和低效性
1017 */
1118public class Employee implements Comparable <Employee > {
1219 private String name ;
Original file line number Diff line number Diff line change 6969 |
7070 | ----- interfaces(接口)
7171 |
72+ | ----- clone(克隆对象)
73+ |
7274 | ----- ...
You can’t perform that action at this time.
0 commit comments