Skip to content

Commit a7a0e9f

Browse files
committed
完成clone
1 parent e50aa87 commit a7a0e9f

File tree

4 files changed

+88
-0
lines changed

4 files changed

+88
-0
lines changed

Part6/clone/CloneTest.java

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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+
}

Part6/clone/Employee.java

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
}

Part6/interfaces/Employee.java

+7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77
* 为了让类实现一个接口,通常需要下面几个步骤:
88
* 1. 将类声明为实现给定的接口
99
* 2. 让接口中的所有方法进行定义
10+
*
11+
* 在这里讨论一下接口与抽象类之间的区别:
12+
* 但是由于Java只支持单继承,而不是C++那样的多重继承,
13+
* 所以使用抽象类的时候,每个类都只能扩展于一个类;
14+
* 但是却可以实现多个接口,
15+
* 接口可以提供多重继承的大多数好处,
16+
* 同时还能避免多重继承的复杂性和低效性
1017
*/
1118
public class Employee implements Comparable<Employee> {
1219
private String name;

README

+2
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,6 @@
6969
|
7070
| ----- interfaces(接口)
7171
|
72+
| ----- clone(克隆对象)
73+
|
7274
| ----- ...

0 commit comments

Comments
 (0)