1、第3章 类与对象3.1.1 面向对象术语 1对象3.1.1 面向对象术语 2类 类被称为模板或者蓝本。对象就是由这些模板或者蓝本产生的。3.1.1 面向对象术语 3继承3.1.1 面向对象术语4接口接口可以描述为类定义的模板3.1.1 面向对象术语 5封装3.1.2 面向对象程序设计方法的优点3.1.2 面向对象程序设计方法的优点 1可重用性3.1.2 面向对象程序设计方法的优点 2可扩展性3.1.2 面向对象程序设计方法的优点 3易于管理和维护3.2 面向对象与UML建模 所以在构建软件的过程中,系统建模是非常关键的步骤,所以OOP也与建模紧密地结合在一起。3.2.1 为什么需要建模 建模是
2、一项经过检验并被广为接受的工程技术。建立房屋和大厦的建筑模型,能帮助用户得到实际建筑物的印象,甚至可以建立数学模型来分析大风或地震对建筑物造成的影响。3.2.2 UML建模语言UML就是统一建模语言(Unified Modeling Language),是由OMG组织(Object Management Group,对象管理组织)在1997年发布的。UML的目标之一就是为开发团队提供标准通用的设计语言来开发和构建计算机应用。UML提出了一套IT专业人员期待多年的统一的标准建模符号。通过使用UML,这些人员能够阅读和交流系统架构和设计规划就像建筑工人多年来所使用的建筑设计图一样。3.2.3 UM
3、L的面向对象分析设计 运用UML进行面向对象的系统分析设计,其过程通常由以下3个部份组成。1识别系统的用例和角色 2进行系统分析,并抽取类 3系统设计,并设计类及其行为3.3 Java语言与面向对象特性 Java是完全面向对象的语言。类是Java程序中最基本的单元。3.4 类的定义和对象的创建3.4.1 类的基本结构 类是构造对象的模板或蓝图。可以通过类声明来定义类,然后使用类来创建用户需要的对象。3.4.2 类之间的关系 在面向对象思想中,类之间存在以下几种常见的关系。1“USES-A”关系“若类A的方法操纵了类B(对象)的成员,则称之为类A“USES-A”(用到了)类B。2“HAS-A”关
4、系“HAS-A”关系是一种拥有关系,若类A中有B类型的成员引用变量,则类A“HAS-A”(拥有)类B。3“IS-A”关系 若类A是类B子类的一种,则可以说类A“IS-A”(是一种)类B3.4.3 构造函数 在创建对象时,对象的成员可以由构造函数方法进行初始化。构造函数是一种特殊的方法,它具有和它所在的类完全一样的名字。一旦定义好一个构造函数,创建对象时就会自动调用它。构造函数没有返回类型,这是因为一个类的构造函数的返回值的类型就是这个类本身。3.4.4 类成员 定义了类之后,就可以在类体中声明两种类的成员,成员变量与成员方法。1成员变量的使用 成员变量就是类的属性,类定义中的属性指定了一个对象
5、区别于其他对象的值。2成员变量的初始值 每当创建一个对象后,如果对象有成员变量,则系统会自动为其分配一个初始值,3.4.5 对象的创建有了类就可以利用其来创建对象了,在Java中创建对象很简单,只要使用new关键字即可。如下代码创建了Student类的对象。Student s=new Student();由类创建对象的过程称为实例化,每个对象是类的一个实例,说明了类与对象的不同之处。学生类是对什么是学生做定义,而王强、李勇和马跃是对象,是学生类的实例。3.5 方 法 在Java中,对对象的操作由方法来完成。要使一个对象完成某些工作,就要调用其相应的方法。方法实际上描述的是一个行为,一种功能3.
6、5.1 方法的定义 方法的基本组成包括:方法的声明以及方法体,基本语法如下。返回值类型 方法名(参数序列)方法体 3.5.2 方法的重载 方法重载是指在同一个类里面,有两个或两个以上具有相同名称,不同参数序列的方法。例如,三角型类可以定义多个名称为area的计算面积的方法,有的接收底和高做参数,有的接收3条边做参数。1方法重载的规则 2重载方法的匹配3.5.3 递归 递归的方式分为2种:直接递归和间接递归3.6 静 态 成 员 使用static关键字把成员声明为静态成员。静态变量也叫类变量,非静态变量叫实例变量 静态成员最主要的特点是它不属于任何一个类的对象,它不保存在任意一个对象的内存空间中
7、,而是保存在类的公共区域中。所以任何一个对象都可以直接访问该类的静态成员,都能获得相同的数据值。修改时,也在类的公共区域修改。3.6.1 静态方法和静态变量 通常情况下,方法必须通过它的类对象访问。在方法的声明前面加上static即可。使用static关键字的方法即静态方法。如果一个方法被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。但是在静态方法中,不能以任何方式引用this或super。3.6.2 静态变量和常量在Java中没有一个直接的修饰符来实现常量,而是通过静态成员变量的方式来实现的,如下代码说明了这个问题。1/声明3个常量X、Y、Z2public
8、 static final int X=10;3static public final int Y=20;4final static public int Z=40;static表示属于类,不必创建对象就可以使用,因为常量应该不依赖于任何对象,final表示值不能改变。一般用作常量的静态成员变量访问权限都设置为public,因为常量应该允许所有类或对象访问。3.6.3 静态成员的访问可以使用“.”的语法调用静态成员变量。3.6.4 main()方法 程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是public s
9、tatic void 类型的,方法必须接收一个字符串数组的参数等等。因为main()方法是由Java虚拟机调用的,所以必须为public,虚拟机调用main()方法的时候不需要产生任何对象,所以main方法声明为static,且不需要返回值,所以声明为void 所以最终格式如下所示。public static void main(String args)3.6.5 Factory方法 Java的静态方法有一种常见的用途,就是使用Factory方法产生不同风格的对象 Factory方法就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A(),Factory
10、Method也是用来创建实例对象的3.7 包 使用包的目的之一就是可以在同一个项目中使用名称相同的类 假如两个开发人员不约而同地建立了两个相同名字的类,只要将其放置在不同的包中,就不会产生冲突。3.7.1 包的定义 要想将类放入指定的包中,就必须使用package语句,语法如下。package;package语句必须放在源文件的最前面 java.lang,这就表示此源文件中的类在java包下的lang子包中3.7.2 类的导入 当一个类要使用与自己处在同一个包中的类时,直接访问即可。若要使用其他包中的类就必须使用import语句,基本语法如下。import.*;import.类名;3.7.3
11、静态导入 从Java SE 5.0开始,导入语句不但可以导入类,还具有导入静态方法和静态成员变量的功能,不过需要在关键字“import”和包名之间添加关键字“static”,语法如下。import static.*;import static.;3.8 成员的访问控制 成员的访问是指以下两种不同的操作。一个类中的方法代码是否能够访问(调用)另一个类中的成员。一个类是否能够继承其父类的成员。3.8.1 公共类型:public 公共类型使用public关键字来进行修饰,当一个成员被声明为public时,所有其他类,无论该类属于哪个包,均能够访问该成员。对于继承而言,规则为如果父类的成员声明为pub
12、lic,那么无论这两个类是否在同一个包中,该子类都能继承其父类的该成员。3.8.2 私有类型:private 标识为私有类型的成员用private关键字修饰,其不能被该成员所在类之外的任何类中的代码访问。对于继承而言,规则为如果父类的成员声明为private,子类在任何情况下都不能继承该成员。3.8.3 默认类型:default 具有此访问权限的成员,只对与此成员所属类在同一个包中的类是可见的。也就是说,对同一个包中的类,默认类型相当于public 而对包外的类则相当于private。下面的两段代码说明了默认类型的使用。3.8.4 保护类型:protected当访问该成员的类位于同一包内,则该
13、类型成员的访问权限相当于public类型。只是有一点区别,若访问该成员的类位于包外,则只有通过继承才能访问该成员。3.9 封 装就是把东西包装起来。换言之,成员变量和方法的定义都包装于类定义之中。通过限定类成员的可见性,可以使类成员中的某些属性和方法能够不被程序的其他部分访问,它们被隐藏了起来,只能在定义的类中使用,这就是面向对象中实现封装的方式。用访问限制修饰符保护成员变量,通常是private。建立公有的访问方法,强制调用代码通过这些方法访问成员变量。3.10 利用系统已有的类 Java类库中提供的几个常用的处理日期时间的类。通过对这几个类的介绍,使读者了解利用系统已有的类的思想。3.10
14、.1 Date类在标准Java类库中包含一个Date类,其对象用来描述一个时间点,如“September 22,2007,23:59:59 GMT”。import java.util.Date;Date类要使用其对象.Date d1=new Date();/表示当前系统时间的对象。Date d2=new Date(106,11,8);/表示1900+106年,11月,8日,过时 System.out.println(new Date();Date d2=new Date(60000);/从1970年1月1日以来经历多少毫秒。Date d1=new Date();Date d2=new Date
15、(60000);System.out.println(d1.after(d2);/true System.out.println(d1.before(d2);/false3.10.2 GregorianCalendar类 使用当前时间构造一个默认的对象 new GregorianCalendar()。GregorianCalendar cal=new GregorianCalendar();System.out.println(cal);java.util.GregorianCalendartime=1285743032156,areFieldsSet=true,areAllFieldsSet
16、=true,lenient=true,zone=sun.util.calendar.ZoneInfoid=Asia/Shanghai,offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2010,MONTH=8,WEEK_OF_YEAR=40,WEEK_OF_MONTH=5,DAY_OF_MONTH=29,DAY_OF_YEAR=272,DAY_OF_WEEK=4,DAY_OF_WEEK_I
17、N_MONTH=5,AM_PM=1,HOUR=2,HOUR_OF_DAY=14,MINUTE=50,SECOND=32,MILLISECOND=156,ZONE_OFFSET=28800000,DST_OFFSET=0 GregorianCalendarGregorianCalendar(int year,int month,int dayOfMonth)GregorianCalendarGregorianCalendar(int year,int month,int dayOfMonth,int hourOfDay,int minute)GregorianCalendar cal=new G
18、regorianCalendar(1978,8,8);1978年9月8日 addadd(int field,int amount)/为给定的日历字段添加或减去指定的时间量 public int getget(int field)/返回给定日历字段的值 setset(int field,int value)/将给定的日历字段设置为给定值。setset(int year,int month,int date)/设置日历字段 YEAR、MONTH 和 DAY_OF_MONTH 的值。setset(int year,int month,int date,int hourOfDay,int minute
19、)/设置日历字段 YEAR、MONTH、DAY_OF_MONTH、HOUR_OF_DAY 和 MINUTE 的值。setTimesetTime(Date date)/使用给定的 Date 设置此 Calendar 的时间。Date Date getTimegetTime()/返回一个表示此 Calendar 时间值例子3-32package chapter03.sample3_32;import java.util.*;public class Sample3_32 public static void main(String args)/创建当前日历对象GregorianCalendar n
20、ow=new GregorianCalendar();/从当前时期对象中取出时间日期对象Date date=now.getTime();/将时间日期对象按字符串形式打印System.out.println(date.toString();/重新将时间对象设置到日期对象中now.setTime(date);/从当前日期对象中取出当前月份、日期int today=now.get(Calendar.DAY_OF_MONTH);int month=now.get(Calendar.MONTH);/设置日期为本月开始日期now.set(Calendar.DAY_OF_MONTH,1);/获取本月开始日期
21、在一周中的编号int week=now.get(Calendar.DAY_OF_WEEK);/打印日历头并换行System.out.println(星期日 星期一 星期二 星期三 星期四 星期五 星期六);/设置当前月中第一天的开始位置for(int i=Calendar.SUNDAY;i week;i+)System.out.print();/按规格循环打印当前月的日期数字while(now.get(Calendar.MONTH)=month)/取出当前日期int day=now.get(Calendar.DAY_OF_MONTH);/设置日期数字小于10与不小于10两种情况的打印规格if(day 10)/设置当前日期的表示形式if(day=today)System.out.print();elseSystem.out.print(+day+);else/设置当前日期的表示形式if(day=today)System.out.print();elseSystem.out.print(+day+);/设置什么时候换行if(week=Calendar.SATURDAY)System.out.println();/设置日期与星期几为下一天now.add(Calendar.DAY_OF_MONTH,1);week=now.get(Calendar.DAY_OF_WEEK);