<Core Java> 4.2 使用现有类

4.14类之间的关系
1.依赖(“use-a”):一个类的方法操纵另一个类的对象。程序设计时应尽可能将这种关系减至最少,即降低耦合度。

2.聚合(“has-a”):意味着类A的对象包含了类B的对象

3.继承(“is-a”)


4.2.1对象与对象变量
1.要使用对象就必须先构造对象。使用构造器构造新实例。

2.构造器名要与类名相同。例如:Date类的构造器名为Date。要构造一个Date对象要在构造器前加new操作符。如:new Date();

3.将对象传递给一个方法:
System.out.println(new Date());

4.也可以将方法应用于刚创建的对象上:
String s = new Date().toString;    //使用“.”来调用方法

5.上面的3和4两个例子所构造的对象只是用了一次,要重复使用构造的对象就要将对象放在一个变量中:
Date birthday = new Date();    //birthday为变量,之后要使用构造的对象只需使用该变量即可,如:String s = birthday.toString;

注意:对象与对象变量的区别,如:Date age;    //定义一个对象变量age,它可以引用Date类型的对象,但是age不是一个对象,所以语句:s = age.toStirng    会产生编译错误。必须要先初始化对象变量age,有两种方法:
age = new Age();    //构造新对象初始化变量
age = birthday;    //引用已存在的对象

6.一定要认识到一个对象变量没有包含一个对象,仅仅是引用一个对象。
在Java中对象变量的值都是对储存在另一个地方的一个对象的引用。new操作符返回的值也是一个引用。
例如:Date birthday = new Date();
Java对象变量可以看成C的指针;Java中不允许没有初始化的对象变量存在,这就保证了不会产生随机的指针;并且垃圾收集器会处理内存泄漏问题。

4.2.3更改器方法与访问器方法
1、要访问一个类中封装的数据,要先初始化这个对象(new一个对象使其实例化),再调用该类所包含的相应方法来实现。
GregorianCalendar now = new GregorianCalendar();
int month = now.get(Calendar.MONTH);
int weekday = now.get(Calendar.DAY_OF_WEEK);

2、调用set方法改变对象的状态:
deadline.set(Calendar.YEAR, 2012);
deadline.set(Calendar.MONTH, Calendar.APRIL);
deadline.set(Calendar.DAY_OF_MONTH, 15);
(还有一个更简便的设置年月日的方法:dealine.set(2012, Calendar.APRIL, 15);

3、给指定的时间对象增加天数,星期数,月份
deadline.add(Calendar.MONTH, 3);//move dealine by 3 months
如果给定的值是负数,日期向后移。

小结:get方法与set和add方法区别在于,get方法只是查看并返回对象的状态(仅访问实例域不修改的方法称为访问器方法);set和add方法是对对象的状态进行修改(对实例域进行修改的方法称为更改器方法)。
扩展:在C++中带有const后缀的方法是访问器,默认的是更改器;在Java中没有明显的区分,通常访问器方法名前加get,而更改器前加set。

4、如果一直年月日要创建一个包含该事件的Date对象,因为Date对象不知道如何处理日历,所以要构造一个GregorianCalendar对象再调用它的getTime方法:
GregorianCalendar calendar = new GregorianCalendar(year, month, day);
Date hireDay = calendar.getTime();
与之相法,如果要湖区Date对象中的年月日呢?
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(hirDay);
int yeat = calendar.get(Calendat.YEAR);

5、应用GregorianClalendar类的程序显示当前月的日历,效果图为:
(*号表示当前日)
该程序的关键步骤:
(1)
构造一个日历对象,并用当前的时间和日期初始化
GregorianCalendar d = new GregorianCalendar();
int today = d.get(Calendar.DAY_OF_MONTH);
int month = d.get(Calendar.MONTH);
(2)
将d设置为这个月的第一天,并获取这一天为星期几:
d.set(Calendar.DAY_OF_MONTH, 1);
int weekday = d.get(Calendar.DAY_OF_WEEK);
如果这个月第一天为星期日,变量weekday就设置为Calendar.SUNDAY,以此类推。
注意,日历的第一行是缩进的,所以月份的第一天指向相应的星期几。因为每个星期的第一天存在着约定                                                         习惯上的不同,所以要能够随机应变。
Java虚拟机非常注重当前用户的所在地,不同地区存在着不同的格式习惯,包括非星期的起始日以及一周中每天的命名方式。

提示:要看到不同地区的程序输出,在main方法的第一行添加代码:Locale.setDefault(Locale.ITALY) ;
(3)
用getFirstDayOfWeek方法获取当前地区一周的起始日。为了确定日历第一行的缩进,将日历对象的日减1,直到一周的第一天为止:
int firstDayOfWeek = d.getFirstDayOfWeek();
int indent = 0;
while (weekday != firstDayOfWeek) {
    indent++;
    d.add(Calendar.DAY_OF_MONTH, -1)
    weekday = d.get(Calendar.DAY_OF_WEEK);
}
(4)
输出表示星期几名称的头。调用DateFormatSymbols类方法实现。
String[] weekdayNames = new DateFormatSymbols().getShortWeekdays();
getShortWeekdays方法返回用户语种所命名的表示星期几的缩写(例如:英文讲返回“Sun”、“Mon”)数组用星期几做索引,循环打印:
do {
    System.out.printf("%4s",weekdayNames[]);
    d.add(Calendar.DAY_OF_MONTH, 1);
    weekday = d.get(Calendar.DAY_OF_WEEK);
}
while(weekday != firstDayOfWeek);
System.out,println();
(5)
至此已做好打印日历内容的准备了。第一行进行缩进,将日期对象设置为月份的起始日。在循环中用d记录一个月中的每一天。
每次迭代过程打印日期值。若d是当前日期,打印日期值后再打印一个*。每周的第一天,要换行打印。然后将d设置为下一天:d.add(Calendar.DAY_OF_MONTH, 1);
何时结束呢?只要d还指示当月就继续迭代:
do{
....
}
while(d.get(Calendar.MONTH) == month);

(6)

完整源代码

  1. import java.text.DateFormatSymbols;  
  2. import java.util.Calendar;  
  3. import java.util.GregorianCalendar;  
  4.   
  5.   
  6. public class CalendarTest {  
  7.     public static void main(String[] args) {  
  8.           
  9.         //construct d as currenr date  
  10.         GregorianCalendar d = new GregorianCalendar();  
  11.           
  12.         //获取当前的月日  
  13.         int today = d.get(Calendar.DAY_OF_MONTH);  
  14.         int month = d.get(Calendar.MONTH);  
  15.           
  16.         //设置d为这个月的第一天,并获取相应的星期几  
  17.         d.set(Calendar.DAY_OF_MONTH, 1);  
  18.         int weekday = d.get(Calendar.DAY_OF_WEEK);  
  19.           
  20.         //获取当前地区一周的起始日  
  21.         int firstDayOfWeek = d.getFirstDayOfWeek();  
  22.           
  23.         //确定这个月第一行的缩进量  
  24.         int indent = 0;  
  25.         while (weekday != firstDayOfWeek) {  
  26.             indent++;  
  27.             d.add(Calendar.DAY_OF_MONTH, -1);  
  28.             weekday = d.get(Calendar.DAY_OF_WEEK);  
  29.         }  
  30.           
  31.         //创建日历表头星期数的名字  
  32.         String[] weekdayNames = new DateFormatSymbols().getShortWeekdays();  
  33.         do {  
  34.             System.out.printf("%4s", weekdayNames[weekday]);  
  35.             d.add(Calendar.DAY_OF_MONTH, 1);  
  36.             weekday = d.get(Calendar.DAY_OF_WEEK);  
  37.         } while (weekday != firstDayOfWeek);  
  38.         System.out.println();  
  39.           
  40.           
  41.         for (int i = 1;i <= indent; i++)  
  42.             System.out.print("  ");  
  43.           
  44.         d.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);  
  45.         do {  
  46.             //开始打印日历  
  47.             int day = d.get(Calendar.DAY_OF_MONTH);  
  48.             System.out.printf("%3d", day);  
  49.               
  50.             //标记当前日期  
  51.             if (day == today) {  
  52.                 System.out.print("*");  
  53.             }  
  54.             else {  
  55.                 System.out.print(" ");  
  56.             }  
  57.               
  58.             //将d设置为下一天  
  59.             d.add(Calendar.DAY_OF_MONTH, 1);  
  60.             weekday = d.get(Calendar.DAY_OF_WEEK);  
  61.               
  62.             //换行打印每周的第一天  
  63.             if (weekday == firstDayOfWeek) {  
  64.                 System.out.println();  
  65.             }  
  66.         } while (d.get(Calendar.MONTH) == month);  
  67.           
  68.         if(weekday != firstDayOfWeek) System.out.println();  
  69.     }  
  70.   
  71. }  
posted @ 2013-02-27 18:07  vincent_hv  阅读(215)  评论(0编辑  收藏  举报