第5讲 类的重用_第1页
第5讲 类的重用_第2页
第5讲 类的重用_第3页
第5讲 类的重用_第4页
第5讲 类的重用_第5页
已阅读5页,还剩124页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第五讲类的重用目录5.1类的继承5.2Object类5.3终结类与终结方法5.4抽象类5.5类的组合5.6包的应用5.7本章小结5.1类的继承类的继承一种由已有的类创建新类的机制,是面向对象程序设计的基石之一通过继承,可以根据已有类来定义新类,新类拥有已有类的所有功能Java只支持类的单继承,每个子类只能有一个直接父类父类是所有子类的公共属性及方法的集合,子类则是父类的特殊化继承机制可以提高程序的抽象程度,提高代码的可重用性基类(baseclass)也称超类、父类(superclass)是被直接或间接继承的类派生类(derived-class)也称子类(subclass)继承其他类而得到的类继承所有祖先的状态和行为(私有除外)派生类可以增加变量和方法派生类也可以覆盖(override)继承的方法5.1.1继承的概念

——基类和派生类类的继承子类对象与父类对象存在“ISA”(或“iskindof”)的关系5.1.1继承的概念——is_a关系类的继承动物类层次举例5.1.1继承的概念

——图5_1一般具体动物蛇蜥蜴鲸爬行动物哺乳动物狗巨蜥壁虎壁虎是一种蜥蜴爬行动物是动物的一种类的继承举例5.1.1继承的概念

——又一个例子类的继承派生类产生的对象从外部来看,它应该包括与基类相同的接口可以具有更多的方法和数据成员其内包含着一个基类类型的子对象5.1.1继承的概念

——派生类对象5.1.2继承的语法继承的语法限定词class子类extends

父类implement接口序列{ //类体}类的继承在一个公司中,有普通员工(Employees)及管理人员(Magagers)两类人员职员对象(Employees)可能有的属性信息包括员工号(employeeNumber)姓名(name)地址(address)电话号码(phoneNumber)管理人员(Managers)除具有普通员工的属性外,还可能具有下面的属性职责(responsibilities)所管理的职员(listOfEmployees)5.1.2继承的语法(续)

——例5_1类的继承Employee与Manager的类图5.1.2继承的语法(续)

——例5_1EmployeeemployeeNumbe:

intname:Stringaddress:StringphoneNumber:StringManagerresponsibilities:StringlistOfEmployees:String类的继承//父类EmployeeclassEmployee{

int

employeeNumbe;Stringname,address,phoneNumber;}//子类ManagerclassManagerextendsEmployee{//子类增加的数据成员Stringresponsibilities,listOfEmployees;}5.1.2继承的语法(续)

——例5_1类的继承设有三个类:Person,Employee,Manager。其类层次如图:5.1.2继承的语法(续)

——例5_2PersonEmployeeManager类的继承publicclassPerson{publicStringname;publicStringgetName(){returnname;}}publicclassEmployeeextendsPerson

{

publicint

employeeNumber;

publicint

getEmployeeNumber()

{

returnemployeeNumber;

}}publicclassManagerextendsEmployee{publicString

responsibilities;

publicString

getResponsibilities(){

returnresponsibilities;}}5.1.2继承的语法(续)

——例5_2类的继承publicclassExam5_2Test{publicstaticvoidmain(Stringargs[]){

Employee

li=newEmployee();

="LiMing";

li.employeeNumber=123456;

System.out.println(li.getName());

System.out.println(li.getEmployeeNumber());

Managerhe=newManager();="HeXia";

he.employeeNumber=543469;he.responsibilities="Internetproject";

System.out.println(he.getName());

System.out.println(he.getEmployeeNumber());

System.out.println(he.getResponsibilities());}}5.1.2继承的语法(续)

——例5_2测试类的继承运行结果LiMing123456HeXia543469Internetproject说明子类不能直接访问从父类中继承的私有属性及方法,但可使用公有(及保护)方法进行访问5.1.2继承的语法(续)

——例5_2测试结果类的继承publicclassB{publicinta=10;

private

int

b=20;protectedintc=30;

publicint

getB(){returnb;}

}publicclassAextendsB{publicintd;publicvoidtryVariables(){

System.out.println(a);//允许

System.out.println(b);//不允许

System.out.println(getB());//允许

System.out.println(c);//允许}}5.1.2继承的语法(续)

——例5_3类的继承5.1.3隐藏和覆盖隐藏和覆盖子类对从父类继承来的属性变量及方法可以重新定义类的继承classParent

{

int

aNumber;}classChildextendsParent{floataNumber;}属性的隐藏子类中声明了与父类中相同的成员变量名,则从父类继承的变量将被隐藏子类拥有了两个相同名字的变量,一个继承自父类,另一个由自己声明当子类执行继承自父类的操作时,处理的是继承自父类的变量,而当子类执行它自己声明的方法时,所操作的就是它自己声明的变量5.1.3隐藏和覆盖(续)

——属性的隐藏如何访问被隐藏的父类属性调用从父类继承的方法,则操作的是从父类继承的属性使用super.属性5.1.3隐藏和覆盖(续)

——访问被隐藏的父类属性属性的隐藏举例classA1{

int

x=2;publicvoidsetx(inti){x=i;}voidprinta(){

System.out.println(x);}

}5.1.3隐藏和覆盖(续)

——例5_4classB1extendsA1{

int

x=100;voidprintb(){super.x=super.x+10;

System.out.println("super.x="+super.x+"x="+x);}}publicclassExam5_4Test{publicstaticvoidmain(String[]args){A1a1=newA1();a1.setx(4);a1.printa();B1b1=newB1();b1.printb();b1.printa();

b1.setx(6);//将继承来的x值设置为6

b1.printb();b1.printa();a1.printa();}}5.1.3隐藏和覆盖(续)

——例5_4测试运行结果4super.x=12x=10012super.x=16x=1001645.1.3隐藏和覆盖(续)

——例5_4运行结果子类不能继承父类中的静态属性,但可以对父类中的静态属性进行操作。如在上面的例子中,将“intx=2;”改为“staticintx=2;”,再编译及运行程序,会得到下面的结果4super.x=14x=10014super.x=16x=1001616在上面的结果中,第一行及最后一行都是语句“a1.printa();”输出的结果,显然类B中的printb()方法修改的是类A中的静态属性x5.1.3隐藏和覆盖(续)

——例5_4运行结果类的继承方法覆盖如果子类不需使用从父类继承来的方法的功能,则可以声明自己的同名方法,称为方法覆盖覆盖方法的返回类型,方法名称,参数的个数及类型必须和被覆盖的方法一模一样只需在方法名前面使用不同的类名或不同类的对象名即可区分覆盖方法和被覆盖方法覆盖方法的访问权限可以比被覆盖的宽松,但是不能更为严格5.1.3隐藏和覆盖(续)

——方法覆盖类的继承方法覆盖的应用场合子类中实现与父类相同的功能,但采用不同的算法或公式在名字相同的方法中,要做比父类更多的事情在子类中需要取消从父类继承的方法5.1.3隐藏和覆盖(续)

——方法覆盖的应用场合类的继承必须覆盖的方法派生类必须覆盖基类中的抽象的方法,否则派生类自身也成为抽象类.不能覆盖的方法基类中声明为final的终结方法基类中声明为static的静态方法调用被覆盖的方法super.overriddenMethodName();5.1.3隐藏和覆盖(续)

——方法覆盖的注意事项5.1.4有继承时的构造方法构造方法简介构造方法是类的一种特殊方法,其名字必须与所在的类的名字完全相同,并且不返回任何数据类型,也不能是void类型。构造方法可以重载(即有多个同名但不同参数序列的构造方法),但不能从父类继承。在Java中,使用构造方法是生成实例对象的唯一方法。若在类的声明中没有声明构造方法,则Java会自动提供一个默认的构造方法来生成对象,对象的属性为零或空。类的继承5.1.4有继承时的构造方法有继承时的构造方法遵循以下的原则子类不能从父类继承构造方法好的程序设计方法是在子类的构造方法中调用某一个父类构造方法,调用语句必须出现在子类构造方法的第一行,可使用super关键字如子类构造方法的声明中没有明确调用父类构造方法,则系统在执行子类的构造方法时会自动调用父类的默认构造方法(即无参的构造方法)this关键字用来调用自身的构造函数,super关键字用来调用基类的构造函数

类的继承publicclassPerson{

protectedStringname,phoneNumber,address;

publicPerson()

{this("","","");}

publicPerson(StringaName,StringaPhoneNumber,StringanAddress)

{name=aName;

phoneNumber=aPhoneNumber;address=anAddress;}}5.1.4有继承时的构造方法(续)

——例5_5publicclassEmployeeextendsPerson{protectedint

employeeNumber;protectedStringworkPhoneNumber;

publicEmployee(){//此处隐含调用构造方法Person()this(0,"");}

publicEmployee(int

aNumber,StringaPhoneNumber){//此处隐含调用构造方法Person()

employeeNumber=aNumber;

workPhoneNumber=aPhoneNumber;}}5.1.4有继承时的构造方法(续)

——例5_5publicclassProfessorextendsEmployee{protectedStringresearch;

publicProfessor(){super();research="";}

publicProfessor(int

aNumber,StringaPhoneNumber,StringaResearch){

super(aNumber,aPhoneNumber);research=aResearch;}}5.1.4有继承时的构造方法(续)

——例5_5在一个公司管理信息系统中,包括普通员工(Employees),其可能有的属性信息包括员工号(employeeNumber)姓名(name)地址(address)电话号码(phoneNumber)管理者(Magagers),除具有普通员工所具有的属性及行为外,还具有下面的属性和行为职责(responsibilities)所管理的职员(listOfEmployees)工资的计算方法与一般员工不同;福利与一般员工不同顾客(Customers),可能有的属性信息包括姓名(name)地址(address)电话号码(phoneNumber)5.1.5应用举例

——例5_6类的继承类层次结构5.1.5应用举例(续)

——例5_6PersonEmployeeManagerCustomer类的继承5.2Object类Object类Java程序中所有类的直接或间接父类,类库中所有类的父类,处在类层次最高点包含了所有Java类的公共属性,其构造方法是Object()Object类定义了所有对象必须具有的状态和行为,较主要的方法如下publicfinalClassgetClass()获取当前对象所属的类信息,返回Class对象publicStringtoString()返回当前对象本身的有关信息,按字符串对象返回publicboolean

equals(Objectobj)比较两个对象是否是同一对象,是则返回trueprotectedObjectclone()生成当前对象的一个拷贝,并返回这个复制对象publicint

hashCode()返回该对象的哈希代码值protectedvoidfinalize()throwsThrowable

定义回收当前对象时所需完成的资源释放工作用户定义的类不可以覆盖终结方法,即有final修饰的方法5.2Object类(续)

——包含的主要方法Object类相等和同一的概念两个对象具有相同的类型,及相同的属性值,则称二者相等(equal)如果两个引用变量指向的是同一个对象(即两个变量指向同一内存地址),则称这两个变量(对象)同一(identical)两个对象同一,则肯定相等两个对象相等,不一定同一比较运算符“==”判断的是这两个对象是否同一5.2Object类(续)

——相等和同一Object类判断两个对象是否同一publicclassExam5_7{ publicstaticvoidmain(Stringargs[]){

BankAccounta=newBankAccount("Bob",123456,100.00f);

BankAccountb=newBankAccount("Bob",123456,100.00f);

if(a==b)

System.out.println("YES");else

System.out.println("NO");}}BankAccount类在4.5.1中声明,此程序运行的结果为“NO”,原因是使用等号“==”判断的是两个对象是否同一,显然a和b是两个对象5.2Object类(续)

——例5_7Object类修改刚才的程序publicclassExam5_7{ publicstaticvoidmain(Stringargs[]){

BankAccounta=newBankAccount("Bob",123456,100.00f);

BankAccountb=a;if(a==b)

System.out.println("YES");else

System.out.println("NO");}}将a所指对象的引用赋给b,因此a与b指向的是同一个对象,a与b同一。输出结果为“YES”5.2Object类(续)

——例5_7Object类equals方法由于Object是类层次结构中的树根节点,因此所有其他类都继承了equals()方法Object类中的equals()方法的定义如下,可见,也是判断两个对象是否同一publicbooleanequals(Objectx){returnthis==x;}5.2Object类(续)

——equals方法Object类Object类中equals方法的使用举例publicclassEqualsTest{ publicstaticvoidmain(Stringargs[]){

BankAccounta=newBankAccount("Bob",123456,100.00f);

BankAccountb=newBankAccount("Bob",123456,

100.00f);if(a.equals(b))

System.out.println("YES");else

System.out.println("NO");}}由于不是同一对象,运行结果仍然是“NO”5.2Object类(续)

——例5_8equlas方法的重写要判断两个对象各个属性域的值是否相同,则不能使用从Object类继承来的equals方法,而需要在类声明中对equals方法进行重写String类中已经重写了Object类的Equals方法,可以判别两个字符串是否内容相等5.2Object类(续)

——equals方法的重写Object类总结基础类型变量只能比较是否相等,不能比较是否同一,所以只能使用==来进行比较,基础类型变量不能使用equals方法。String是一种类,不属于基础类型,但String类型的变量无论是==操作符还是equals方法,都是用来判断两个变量是否相等,无法比较是否同一。对于其他Object类,==和equals都是判断是否同一,无法判断是否值相等。如果想判断两个Object类型对象是否相等,必须重写equals方法。5.2Object类(续)

——equals方法的重写Object类equals方法重写的方法与步骤

先判断两个Object对象的类型是否属于相同的类,可使用getClass()方法或者instanceof关键字。(instanceof——二元操作符,测试它左侧的对象是否是它右侧的类的实例)。将被比较的两个对象进行强制类型转换,转换为同一种实际类型。判断两个对象的所有属性值是否相等。5.2Object类(续)

——equals方法的重写Object类equals方法重写举例

classApple{

privateStringcolor;

privatebooleanripe;

publicbooleanequals(Objectobj){

if(objinstanceofApple){

//步骤1

Applea=(Apple)obj;

//步骤2

return((this.color==a.color)&&(this.ripe==a.ripe));

}//步骤3

returnfalse;

}

}5.2Object类(续)

——equals方法的重写Object类在BankAccount类中增加equals方法,由于是对Object类中的equals方法进行重写,因此方法定义头必须与Object类中的equals方法完全相同publicbooleanequals(Objectx){if(this.getClass()!=x.getClass()) returnfalse;

BankAccountb=(BankAccount)x;return((this.getOwnerName().equals(b.getOwnerName()))&&(this.getAccountNumber()==b.getAccountNumber())&&(this.getBalance()==b.getBalance()));}5.2Object类(续)

——equals方法的重写Object类equals方法的应用举例publicclassApple{privateStringcolor;privatebooleanripe;publicApple(StringaColor,boolean

isRipe){color=aColor;ripe=isRipe;}publicvoidsetColor(String

aColor){color=aColor;}publicvoidsetRipe(boolean

isRipe){ripe=isRipe;}publicStringgetColor(){returncolor;}publicboolean

getRipe(){returnripe;}publicStringtoString(){if(ripe)return("Aripe"+color+"apple");elsereturn("Anotsoripe"+color+"apple");}Object类5.2Object类(续)

——例5_9publicboolean

equals(Objectobj){if(obj

instanceofApple){Applea=(Apple)obj;return(color.equals(a.getColor())&&(ripe==a.getRipe()));}returnfalse;}}publicclassAppleTester{publicstaticvoidmain(Stringargs[]){Applea=newApple("red",true);Appleb=newApple("red",true);

System.out.println(a+"isequalto"+b+":"+a.equals(b));

System.out.println("aisidenticaltob:"+(a==b));Applec=a;

System.out.println(a+"isequalto"+c+":"+a.equals(c));

System.out.println("aisidenticaltoc:"+(a==c));}}5.2Object类(续) ——例5_9Object类运行结果AriperedappleisequaltoAriperedapple:trueaisidenticaltob:falseAriperedappleisequaltoAriperedapple:trueaisidenticaltoc:true5.2Object类(续)

——例5_9运行结果Object类Clone方法根据已存在的对象构造一个新的对象在根类Object中被定义为protected,所以需要覆盖为public实现Cloneable

接口,赋予一个对象被克隆的能力(cloneability)classMyObjectimplementsCloneable

{//…}Object类5.2Object类(续)

——Clone方法略finalize方法在对象被垃圾回收器回收之前,系统自动调用对象的finalize方法如果要覆盖finalize方法,覆盖方法的最后必须调用super.finalize5.2Object类(续)

——finalize方法Object类getClass方法final方法,返回一个Class对象,用来代表对象隶属的类通过Class对象,你可以查询Class对象的各种信息:比如它的名字,它的基类,它所实现接口的名字等。voidPrintClassName(Object

obj){

System.out.println("TheObject'sclassis"+

obj.getClass().getName());}5.2Object类(续)

——getClass方法Object类notify、notifyAll、wait方法final方法,不能覆盖这三个方法主要用在多线程程序中5.2Object类(续)

——notify、notifyAll、wait方法Object类5.3终结类与终结方法终结类与终结方法被final修饰符修饰的类和方法终结类不能被继承终结方法不能被当前类的子类重写5.3.1终结类终结类的特点不能有派生类终结类存在的理由安全:黑客用来搅乱系统的一个手法是建立一个类的派生类,然后用他们的类代替原来的类设计:你认为你的类是最好的或从概念上你的类不应该有任何派生类终结类与终结方法声明ChessAlgorithm

类为final类finalclassChessAlgorithm{...}如果写下如下程序:classBetterChessAlgorithmextends

ChessAlgorithm

{…}编译器将显示一个错误Chess.java:6:Can'tsubclassfinalclasses:classChessAlgorithmclassBetterChessAlgorithmextendsChessAlgorithm{^1error5.3.1终结类(续)

——一个例子终结类与终结方法终结方法的特点不能被派生类覆盖终结方法存在的理由对于一些比较重要且不希望子类进行更改的方法,可以声明为终结方法。可防止子类对父类关键方法的错误重写,增加了代码的安全性和正确性提高运行效率。通常,当java运行环境(如java解释器)运行方法时,它将首先在当前类中查找该方法,接下来在其超类中查找,并一直沿类层次向上查找,直到找到该方法为止5.3.2终结方法终结类与终结方法5.3.1终结方法(续)

——例5_10final方法举例classParent{publicParent(){}//构造方法

finaldoublegetPI(){returnMath.PI;}//终结方法}说明getPI()是用final修饰符声明的终结方法,不能在子类中对该方法进行重载,因而如下声明是错的ClassChildextendsParent{

publicChild(){}//构造方法

doublegetPI(){return3.14;}//重写父类中的终结方法,不允许}终结类与终结方法5.4抽象类抽象类代表一个抽象概念的类没有具体实例对象的类,不能使用new方法进行实例化类前需加修饰符abstract可包含常规类能够包含的任何东西,例如构造方法,非抽象方法也可包含抽象方法,这种方法只有方法的声明,而没有方法的实现存在意义抽象类是类层次中较高层次的概括,抽象类的作用是让其他类来继承它的抽象化的特征抽象类中可以包括被它的所有子类共享的公共行为抽象类可以包括被它的所有子类共享的公共属性在程序中不能用抽象类作为模板来创建对象;在用户生成实例时强迫用户生成更具体的实例,保证代码的安全性5.4抽象类(续)

——存在意义将所有图形的公共属性及方法抽象到抽象类Shape。再将2D及3D对象的特性分别抽取出来,形成两个抽象类TwoDimensionalShape及ThreeDimensionalShape2D图形包括Circles、Triangles、Rectangles和Squares3D图形包括Cube、Sphere、或Tetrahedron在UML中,抽象类的类名为斜体,以与具体类相区别5.4抽象类(续)

——几何形状的例子ShapeCircleTriangleRectangleSquareTwoDimensionalShapeThreeDimensionalShapeCubeSphereTetrahedron抽象类例5_6中,如果在应用系统中涉及到的人员只包括:Customers,Employees及Managers。则Person类的子类对象覆盖了应用中的对象,可以将Person类声明为抽象类5.4抽象类(续)

——人员的例子PersonEmployeeManagerCustomer抽象类5.5.1抽象类的声明抽象类声明的语法形式为abstractclassNumber{...}如果写:newNumber();编译器将显示错误5.5.2抽象方法抽象方法声明的语法形式为public

abstract

<returnType><methodName>(...);仅有方法头,而没有方法体和操作实现具体实现由当前类的不同子类在它们各自的类声明中完成抽象类可以包含抽象方法抽象类需注意的问题一个抽象类的子类如果不是抽象类,则它必须为父类中的所有抽象方法书写方法体,即重写父类中的所有抽象方法只有抽象类才能具有抽象方法,即如果一个类中含有抽象方法,则必须将这个类声明为抽象类除了抽象方法,抽象类中还可以包括非抽象方法5.5.2抽象方法(续)

——需注意的问题抽象类抽象方法的优点隐藏具体的细节信息,所有的子类使用的都是相同的方法头,其中包含了调用该方法时需要了解的全部信息强迫子类完成指定的行为,规定其子类需要用到的“标准”行为5.5.2抽象方法(续)

——抽象方法的优点各种图形都需要实现绘图方法,可在它们的抽象父类中声明一个draw抽象方法abstractclassGraphicObject{

intx,y;voidmoveTo(int

newX,int

newY){...}

abstractvoiddraw();}5.5.2抽象方法(续)

——一个绘图的例子抽象类然后在每一个子类中重写draw方法,例如:classCircleextendsGraphicObject{voiddraw(){...}}classRectangleextendsGraphicObject{voiddraw(){...}}5.5.2抽象方法(续)

——一个绘图的例子抽象类LoanLeaseMortgageHouseLoanCarLoan贷款(Loan)分为许多种类,如租借(Lease)、抵押(Mortgage)、房屋贷款(HouseLoan)、汽车贷款(CarLoan)等将Loan声明为抽象类,并指定所有的子类对象都应具有的行为,如计算月还款值(calculateMonthlyPayment),还款(makePayment),取得客户信息(getClientInfo),其中前两个因贷款种类不同计算方法也不同,可声明为抽象方法,Loan的所有子类都必须对这两个抽象方法进行重写publicabstractclassLoan{publicabstractfloatcalculateMonthlyPayment();publicabstractvoidmakePayment(floatamount);publicClientgetClientInfo(){…}}5.5.2抽象方法(续)

——例5_11抽象类5.5类的组合类的组合面向对象编程的一个重要思想就是用软件对象来模仿现实世界的对象现实世界中,大多数对象由更小的对象组成与现实世界的对象一样,软件中的对象也常常是由更小的对象组成Java的类中可以有其他类的对象作为成员,这便是类的组合5.5.1组合的语法组合的语法很简单,只要把已存在类的对象放到新类中即可可以使用“hasa”语句来描述这种关系例如,考虑Kitchen类提供烹饪和冷藏食品的功能,很自然的说“mykitchen'hasa'cooker/refrigerator”。所以,可简单的把对象myCooker和myRefrigerator放在类Kitchen中。格式如下classCooker{//类的语句}classRefrigerator{//类的语句}classKitchen{ CookermyCooker;RefrigeratormyRefrigerator;}类的组合5.5.1组合的语法(续)

——例5_12一条线段包含两个端点publicclassPoint//点类{privateintx,y;//coordinatepublicPoint(intx,inty){this.x=x;this.y=y;}publicint

GetX(){returnx;}publicint

GetY(){returny;}}类的组合classLine//线段类{

privatePointp1,p2;//两端点

Line(Pointa,Pointb){p1=newPoint(a.GetX(),a.GetY());p2=newPoint(b.GetX(),b.GetY());}publicdoubleLength(){returnMath.sqrt(Math.pow(p2.GetX()-p1.GetX(),2)

+Math.pow(p2.GetY()-p1.GetY(),2));}}5.5.1组合的语法(续)

——例5_12类的组合5.5.2组合与继承的比较组合与继承的比较“包含”关系用组合来表达如果想利用新类内部一个现有类的特性,而不想使用它的接口,通常应选择组合,我们需在新类里嵌入现有类的private对象如果想让类用户直接访问新类的组合成分,需要将成员对象的属性变为public“属于”关系用继承来表达取得一个现成的类,并制作它的一个特殊版本。通常,这意味着我们准备使用一个常规用途的类,并根据特定需求对其进行定制类的组合car(汽车)对象是一个很好的例子,由于汽车的装配是故障分析时需要考虑的一项因素,所以有助于客户程序员理解如何使用类,而且类创建者的编程复杂程度也会大幅度降低classEngine{//发动机类 publicvoidstart(){} publicvoidrev(){} publicvoidstop(){}}5.5.2组合与继承的比较(续)

——Car的例子classWheel{//车轮类

publicvoidinflate(int

psi){}}classWindow{//车窗类 publicvoidrollup(){} publicvoidrolldown(){}}classDoor{//车门类 publicWindowwindow=newWindow(); publicvoidopen(){} publicvoidclose(){}}5.5.2组合与继承的比较(续)

——Car的例子类的组合publicclassCar{

public

Engineengine=newEngine();

public

Wheel[]wheel=newWheel[4];

public

Doorleft=newDoor(),right=newDoor();publicCar(){

for(inti=0;i<4;i++) wheel[i]=newWheel(); } publicstaticvoidmain(String[]args){ Carcar=newCar(); car.left.window.rollup(); Car.wheel[0].inflate(72); }}5.5.2组合与继承的比较(续)

——Car的例子类的组合5.5.3组合与继承的结合许多时候都要求将组合与继承两种技术结合起来使用,创建一个更复杂的类类的组合

组合与继承举例classPlate{//声明盘子 publicPlate(inti){

System.out.println("Plateconstructor"); }}classDinnerPlateextendsPlate{//声明餐盘为盘子的子类 publicDinnerPlate(inti){ super(i);

System.out.println("DinnerPlateconstructor"); }}5.5.3组合与继承的结合(续)

——例5_13类的组合classUtensil{//声明器具

Utensil(inti){

System.out.println("Utensilconstructor"); }}classSpoonextendsUtensil{//声明勺子为器具的子类 publicSpoon(inti){ super(i);

System.out.println("Spoonconstructor"); }}5.5.3组合与继承的结合(续)

——例5_13类的组合classForkextendsUtensil{//声明餐叉为器具的子类 publicFork(inti){ super(i);

System.out.println("Forkconstructor"); }}classKnifeextendsUtensil{//声明餐刀为器具的子类 publicKnife(inti){ super(i);

System.out.println("Knifeconstructor"); }}5.5.3组合与继承的结合(续)

——例5_13classCustom{//声明做某事的习惯 publicCustom(inti){System.out.println("Customconstructor");}}publicclass

PlaceSettingextendsCustom{//声明餐桌的布置

Spoonsp;Fork

frk;Knife

kn;

DinnerPlatepl; publicPlaceSetting(inti){ super(i+1); sp=newSpoon(i+2);

frk=newFork(i+3);

kn=newKnife(i+4); pl=newDinnerPlate(i+5);

System.out.println("PlaceSettingconstructor"); } publicstaticvoidmain(String[]args){

PlaceSettingx=newPlaceSetting(9); }}5.5.3组合与继承的结合(续)

——例5_13类的组合运行结果CustomconstructorUtensilconstructorSpoonconstructorUtensilconstructorForkconstructorUtensilconstructorKnifeconstructorPlateconstructorDinnerPlateconstructorPlaceSettingconstructor5.5.3组合与继承的结合(续)

——例5_13运行结果类的组合5.6包的应用包为了解决类名冲突,Java提供包来管理类名空间Java利用包来组织相关的类,并控制访问权限包是一种松散的类的集合,利用包来管理类,可实现类的共享与复用同一包中的类在默认情况下可以互相访问,通常把需要在一起工作的类放在一个包里5.6.1Java基础类库简介Java基础类库Java提供了用于语言开发的类库,称为Java基础类库(JFC,JavaFoundationalClass)

,也称应用程序编程接口(API,ApplicationProgrammingInterface),分别放在不同的包中Java提供的包主要有java.lang,java.io,java.math,java.utiljava.applet,java.awt,java.awt.datatransferjava.awt.event,java.awt.image,java.beans,java.rmi,java.security,java.sql等包的应用语言包(java.lang)语言包java.lang提供了Java语言最基础的类,包括Object类数据类型包裹类(theDataTypeWrapper)字符串类(String、StringBuffer)数学类(Math)系统和运行时类(System、Runtime)类操作类(Class,ClassLoader)5.6.1Java基础类库简介(续)

——语言包包的应用数据包裹类对应Java的每一个基本数据类型(primitivedatatype)都有一个数据包裹类,即可以将每一个基本数据类型的变量转换成一个相应的类对象。每个包裹类都只有一个类型为对应的基本数据类型的属性域5.6.1Java基础类库简介(续)

——数据类型包裹类基本数据类型数据包裹类booleanBooleanbyteBytecharCharactershortShortintIntegerlongLongfloatFloatdoubleDouble包的应用生成数据类型包裹类对象的方法从基本数据类型的变量或常量生成包裹类对象doublex=1.2;Doublea=newDouble(x);Doubleb=newDouble(-5.25);从字符串生成包裹类对象(Character类除外)Doublec=newDouble("-2.34");Integeri=newInteger("1234");已知字符串,可使用valueOf方法将其转换成包裹类对象:Integer.valueOf("125");Double.valueOf("5.15");5.6.1Java基础类库简介(续)

——生成数据类型包裹类对象的方法包的应用得到基本数据类型数据的方法每一个包裹类都提供相应的方法将包裹类对象转换回基本数据类型的数据(即通过包裹类对象相应的value方法转化)anIntegerOValue()//返回int类aCharacterObject.charValue()//返回char类型的数据Integer、Float、Double、Long、Byte及Short类提供了特殊的方法能够将字符串类型的对象直接转换成对应的int、float、double、long、byte或short类型的数据(即通过相应包裹类对象相应的parse方法转化)Integer.parseInt("234")//返回int类型的数据Float.parseFloat("235.78")//返回float类型的数据包的应用5.6.1Java基础类库简介(续)

——得到基本数据类型数据的方法String类该类字符串对象的值和长度都不变化称为常量字符串生成String类对象的方法直接向String对象赋值字符串常量StringaString;aString=“Thisisastring”

调用构造方法生成字符串对象newString();newString(Stringvalue);newString(char[]value);newString(char[]value,intoffset,intcount);newString(StringBufferbuffer);5.6.1Java基础类库简介(续)

——常量字符串类String包的应用5.6.1Java基础类库简介(续)

——String类的常用方法1名称解释intlength()返回字符串中字符的个数charcharAt(intindex)返回序号index处的字符int

indexOf(Strings)在接收者字符串中进行查找,如果包含子字符串s,则返回匹配的第一个字符的位置序号,

否则返回-1Stringsubstring(intbegin,intend)返回接收者对象中序号从begin开始到end-1的子字符串publicString[]split(String

regex)publicString[]split(String

regex,

intlimit)以指定字符为分隔符,分解字符串Stringconcat(Strings)返回接收者字符串与参数字符串s进行连接后的字符串包的应用5.6.1Java基础类库简介(续)

——String类的常用方法2名称解释Stringreplace(charoldChar,charnewChar);将接收者字符串的oldChar替换为newCharint

compareTo(Strings);将接收者对象与参数对象进行比较booleanequals(Strings);接收者对象与参数对象的值进行比较Stringtrim();将接收者字符串两端的空字符串都去掉StringtoLowerCase()将接收者字符串中的字符都转为小写StringtoUpperCase()将接收者字符串中的字符都转为大写包的应用StringBuffer类其对象是可以修改的字符串字符的个数称为对象的长度(length)分配的存储空间称为对象的容量(capacity)与String类的对象相比,执行效率要低一些该类的方法不能被用于String类的对象5.6.1Java基础类库简介(续)

——变量字符串类StringBuffer包的应用生成StringBuffer类的对象newStringBuffer();

生成容量为16的空字符串对象newStringBuffer(intsize);

生成容量为size的空字符串对象newStringBuffer(String

aString);

生成aString的一个备份,容量为其长度+165.6.1Java基础类库简介(续)

——生成StringBuffer类的对象包的应用5.6.1Java基础类库简介(续)

——StringBuffer类的常用方法1名称解释intlength()返回字符串对象的长度intcapacity()返回字符串对象的容量voidensureCapacity(intsize)设置字符串对象的容量voidsetLength(int

len)设置字符串对象的长度。如果len的值小于当前字符串的长度,则尾部被截掉charcharAt(intindex)返回index处的字符包的应用名称解释voidsetCharAt(intindex,charc)将index处的字符设置为cvoidgetChars(intstart,intend,char[]charArray,int

newStart)将接收者对象中从start位置到end-1位置的字符拷贝到字符数组charArray中,从位置newStart开始存放StringBufferreverse()返回将接收者字符串逆转后的字符串StringBuffer

insert(intindex,Objectob)将ob插入到index位置StringBufferappend(Objectob)将ob连接到接收者字符串的末尾5.6.1Java基础类库简介(续)

——StringBuffer类的常用方法2包的应用已知一个字符串,返回将字符串中的非字母字符都删除后的字符串publicclassStringEditor{publicstaticStringremoveNonLetters(String

original){

StringBuffer

aBuffer=newStringBuffer(original.length());charaCharacter;for(inti=0;i<original.length();i++){

aCharacter=original.charAt(i);if(Character.isLetter(aCharacter))

aBuffer.append(new

Character(aCharacter));}returnnewString(aBuffer);}}5.6.1Java基础类库简介(续)

——例5_14包的应用publicclassStringEditorTester{publicstaticvoidmain(Stringargs[]){Stringoriginal="Hello123,MyNameisMark,234Ithinkyouaremyclassmate?!!";

System.out.println(

StringEditor.removeNonLetters(original));}}运行结果HelloMyNameisMarkIthinkyouaremyclassmate5.6.1Java基础类库简介(续)

——例5_14数学类提供一组常量和数学函数,例如E和PI常数求绝对值的abs方法计算三角函数的sin方法和cos方法求最小值、最大值的min方法和max方法求随机数的random方法等其中所有的变量和方法都是静态的(static)是终结类(final),不能从中派生其他的新类5.6.1Java基础类库简介(续)

——数学类(Math)包的应用System类访问系统资源arraycopy()复制一个数组exit()结束当前运行的程序currentTimeMillis()获得系统当前日期和时间等访问标准输入输出流System.in标准输入,表示键盘System.out标准输出,表示显示器Runtime类可直接访问运行时资源totalMemory()

返回系统内存总量freeMemory()返回内存的剩余空间5.6.1Java基础类库简介(续)

——系统和运行时类System、Runtime包的应用Class类提供运行时信息,如名字、类型以及父类Object类中的getClass方法返回当前对象所在的类,返回类型是Class它的getName方法返回一个类的名称,返回值是String它的getSuperclass方法可以获得当前对象的父类ClassLoader类提供把类装入运行时环境的方法5.6.1Java基础类库简介(续)

——类操作类(Class、ClassLoader)包的应用Class类应用举例。publicclassClassTest{publicstaticvoidmain(Stringargs[]){

BankAccount

anAccount=newBankAccount();ClassaClass=anAccount.getClass();

System.out.println(aClass);

System.out.println(aClass.getName());}}运行结果classBankAccountBankAccount5.6.1Java基础类库简介(续)

——例5_15包的应用实用包(java.util)——实现各种不同实用功能日期类:描述日期和时间DateCalendarGregorianCalendar集合类Collection(无序集合)、Set(不重复集合)List(有序不重复集合)、Enumeration(枚举)LinkedList(链表)、Vector(向量)Stack(栈)、Hashtable(散列表)、TreeSet(树)StringTokenizer类允许以某种分隔标准将字符串分隔成单独的子字符串5.6.1Java基础类库简介(续)

——实用包包的应用Date类构造方法Date()获

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论