1,使用系统的类
这里举了个例子,使用GregorianCalendar类和Calendar类来写日历日期方面的应用
View Code
1 import java.util.*;
2
3 public class CalendarTest
4 {
5 public static void main(String[] args)
6 {
7 // construct d as current date
8 GregorianCalendar d = new GregorianCalendar();
9
10 int today = d.get(Calendar.DAY_OF_MONTH);
11 int month = d.get(Calendar.MONTH);
12
13 // set d to start date of the month
14 d.set(Calendar.DAY_OF_MONTH, 1);
15
16 int weekday = d.get(Calendar.DAY_OF_WEEK);
17
18 // get first day of week (Sunday in the U.S.)
19 int firstDayOfWeek = d.getFirstDayOfWeek();
20
21 // indent first line of calendar
22 for (int i = firstDayOfWeek; i < weekday; i++ )
23 System.out.print(" ");
24
25 do
26 {
27 // print day
28 int day = d.get(Calendar.DAY_OF_MONTH);
29 System.out.printf("%3d", day);
30
31 // mark current day with *
32 if (day == today)
33 System.out.print("*");
34 else
35 System.out.print(" ");
36
37 // advance d to the next day
38 d.add(Calendar.DAY_OF_MONTH, 1);//设置日历中的下一天
39 weekday = d.get(Calendar.DAY_OF_WEEK);
40
41 // start a new line at the start of the week
42 if (weekday == firstDayOfWeek)
43 System.out.println();
44 } while (d.get(Calendar.MONTH) == month);
45
46 // the loop exits when d is day 1 of the next month
47
48 // print final end of line if necessary
49 if (weekday != firstDayOfWeek)
50 System.out.println();
51 }
52 }
2,编写你自己的类
1)隐式参数与显式参数
如方法:
1 public void raiseSalary(double byPercent)
2 {
3 double raise = salary * byPercent / 100;
4 salary += raise;
5 }
将调用这个方法的对象的salary实例域设置为新值,例如下面这个调用:
number007.raiseSalary(5);
实际上执行了下面的操作:
1 double raise = number007.salary * 5 / 100;
2 number007.salary += raise;
实际上,任何一个方法都有一个this的隐式参数,你也可以将上面的方法写成这样(显式的将this写出来,有些程序员偏好这样的风格,它将实例域与局部变量区分开来):
public void raiseSalary(double byPercent)
{
double raise = this.salary * byPercent / 100;
this.salary += raise;
}
2)在讲到封装的优点的时候,举出了这样一个破坏封装性的例子:
不要编写返回引用可变对象的访问器方法,这样会破坏封装性。
下例表明了这一点:
1 class Employee
2 {
3 . . .
4 public Date getHireDay()
5 {
6 return hireDay;
7 }
8 . . .
9 private Date hireDay;
10 }
public Date getHireDay访问器就是一个返回引用可变对象的访问器,它的返回值是Date类型的,Date类型的引用是可变的,即你可以不通过类中提供的方法,而通过Date类中的方法来改变Date对象的值,这显然与我们设计private Date HireDay不适应。
3)静态域和静态方法:
看个例子吧,注释写好了
View Code
1 //编写一个Employee类,静态域nextId测试,用static成员nexId来对id进行设置,实现id的递增
2
3 public class StaticTest
4 {
5 public static void main(String[] args)
6 {
7 // fill the staff array with three Employee objects
8 Employee[] staff = new Employee[3];
9
10 staff[0] = new Employee("Tom", 40000);
11 staff[1] = new Employee("Dick", 60000);
12 staff[2] = new Employee("Harry", 65000);
13
14 // print out information about all Employee objects
15 for (Employee e : staff)
16 {
17 e.setId();
18 System.out.println("name=" + e.getName()
19 + ",id=" + e.getId()
20 + ",salary=" + e.getSalary());
21 }
22
23 int n = Employee.getNextId(); // calls static method
24 System.out.println("Next available id=" + n);
25 }
26 }
27
28
29 //Employee类
30
31 class Employee
32 {
33 public Employee(String n, double s)
34 {
35 name = n;
36 salary = s;
37 id = 0;
38 }
39
40 public String getName()
41 {
42 return name;
43 }
44
45 public double getSalary()
46 {
47 return salary;
48 }
49
50 public int getId()
51 {
52 return id;
53 }
54
55 public void setId()//用static成员nexId来对id进行设置,实现id的递增
56 {
57 id = nextId; // set id to next available id
58 nextId++;
59 }
60
61 public static int getNextId()
62 {
63 return nextId; // returns static field
64 }
65
66 public static void main(String[] args) // unit test
67 {
68 Employee e = new Employee("Harry", 50000);
69 System.out.println(e.getName() + " " + e.getSalary());
70 }
71
72 private String name;
73 private double salary;
74 private int id;
75 private static int nextId = 1;
76 }
name=Tom,id=1,salary=40000.0
name=Dick,id=2,salary=60000.0
name=Harry,id=3,salary=65000.0
Next available id=4
4)方法参数
其实只有值传递,测试下传递的过程:
View Code
1 public static void tripleValue(double x) // doesn't work
2 {
3 x = 3 * x;
4 System.out.println("End of method: x=" + x);
5 }
6
7 public static void tripleSalary(Employee x) // works
8 {
9 x.raiseSalary(200);
10 System.out.println("End of method: salary="
11 + x.getSalary());
12 }
13
14 public static void swap(Employee x, Employee y)//doesn't work
15 {
16 Employee temp = x;
17 x = y;
18 y = temp;
19 System.out.println("End of method: x=" + x.getName());
20 System.out.println("End of method: y=" + y.getName());
21 }
5)构造器的相互调用,初始化块,静态块等
下面的代码展示了关于构造器的许多重要特性
1 import java.util.*;
2
3 public class ConstructorTest
4 {
5 public static void main(String[] args)
6 {
7 // fill the staff array with three Employee objects
8 Employee[] staff = new Employee[3];
9
10 staff[0] = new Employee("Harry", 40000);
11 staff[1] = new Employee(60000);
12 staff[2] = new Employee();
13
14 // print out information about all Employee objects
15 for (Employee e : staff)
16 System.out.println("name=" + e.getName()
17 + ",id=" + e.getId()
18 + ",salary=" + e.getSalary());
19 }
20 }
21
22
23 class Employee
24 {
25 // three overloaded constructors
26 public Employee(String n, double s)
27 {
28 name = n;
29 salary = s;
30 }
31
32 public Employee(double s)//在一个构造器中调用另一个构造器
33 {
34 // calls the Employee(String, double) constructor
35 this("Employee #" + nextId, s);
36 }
37
38 // the default constructor
39 public Employee()//空构造器
40 {
41 // name initialized to ""--see below
42 // salary not explicitly set--initialized to 0
43 // id initialized in initialization block
44 }
45
46
47 public String getName()
48 {
49 return name;
50 }
51
52 public double getSalary()
53 {
54 return salary;
55 }
56
57 public int getId()
58 {
59 return id;
60 }
61
62 private static int nextId;//静态域nextId
63
64 private int id;
65 private String name = ""; // instance field initialization
66 private double salary;
67
68 // static initialization block静态块,仅当第一次加载类时,进行一次初始化,这段代码只执行一次
69 static
70 {
71 Random generator = new Random();
72 // set nextId to a random number between 0 and 9999
73 nextId = generator.nextInt(10000);
74 }
75
76 // object initialization block初始化快,无论使用哪个构造器构造对象,都要先运行初始化块然后运行构造器,这种方式不常见
77 {
78 id = nextId;
79 nextId++;
80 }
81 }
参考 :第四章 对象与类