现在的位置: 首页 > 综合 > 正文

对象与类

2012年08月14日 ⁄ 综合 ⁄ 共 5142字 ⁄ 字号 评论关闭

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 }

参考 :第四章  对象与类

抱歉!评论已关闭.