Presentation is loading. Please wait.

Presentation is loading. Please wait.

第四章 Java面向对象程序设计.

Similar presentations


Presentation on theme: "第四章 Java面向对象程序设计."— Presentation transcript:

1 第四章 Java面向对象程序设计

2 4.1 面向对象程序设计的基本概念 对象是客观世界中的某个具体事物。(客车) 事物的特性就是数据(载客数量、燃料容量、耗油均值)
事物的行为就是方法 (行驶、起动、刹车) 特性/数据 行为/方法 面向对象的程序设计方法就是将客观事物抽象成为“类”,并通过类的“继承”实现软件的可扩充性和可重用性。 对象

3 类和对象 类是具有共同特性和行为的事物的抽象,是一种特殊数据类型。在类中包含了数据和与数据有关的操作(方法)。 对象是类的实例。 类 汽车
客车 抽象 实例化

4 封装、继承、多态性 面向对象程序设计的核心技术 通过封装可以隐藏类的实现细节,也可以避免对类中数据的直接操作。类是封装的基本单元。
继承是对类的功能的重用和扩充。 多态性是指方法的名字相同,但实现不同。 Java是一种完全面向对象的程序设计语言。它继承了C++的优点。Java降低了程序的复杂性,实现了代码的可重用性,提高了运行效率。

5 4.2 类的创建 类的声明格式: <类首声明> {<类主体>} 类首声明定义类的名字、访问权限以及与其它类的关系等。
类主体定义类的成员,包括变量(数据)和方法(行为)

6 extends: 表示类和另外一些类(超类)的继承关系; implements: 表示类实现了某些接口;
类首声明: [<修饰符>] class <类名> [extends <超类名>] [implements <接口名>] class: 类定义的关键字; extends: 表示类和另外一些类(超类)的继承关系; implements: 表示类实现了某些接口; 修饰符: 表示类访问权限(public、private等)和一些其它特性(abstract、final等); 例如: public class Date1 声明Date1类,访问权限为public,表示类Date1可以被该类所属的包之外的类使用。

7 <类首声明> { //类首,以下为类主体 <成员变量的声明> <成员方法的声明及实现> }
类主体的结构: <类首声明> {    //类首,以下为类主体 <成员变量的声明> <成员方法的声明及实现> } 成员变量即类的数据,反映了类的属性和状态。 成员方法即类的行为(对数据的操作) 例4.2.1:声明一个日期类Date1 public class Date1 { int year,month,day; //成员变量 public void today( ) { //成员方法 System.out.println(“Date is”+year+”/”+month+”/”+day);

8 例:根据几何中的坐标位置,定义一个Point类
class Point{ private int x,y; public void setPoint( int a, int b){ x=a; y=b; } public int getX(){ return x;} public int getY(){ return y;} public String toString(){ return “[“+x+”,”+y+”]”;

9 [<修饰符>] [static] [final] [transient] <变量类型> <变量名>
成员变量的声明格式: [<修饰符>] [static] [final] [transient] <变量类型> <变量名> static: 表示是一个类成员变量(静态变量); final: 表示是一个常量; (最终成员变量) 例:final double PI= ; transient: 表示一个临时变量 修饰符: 表示变量的访问权限(缺省访问、public、 protected和private) 作用域:整个类。同一类中的所有方法都可以对其访问。并可简单地通过名字来引用。(在方法体内定义的变量是方法变量,作用域只能在方法体内) 例:class Sampleclass{ public int I; method(){ int j; }

10 成员方法的声明格式: [<修饰符>]<返回类型> <方法名> ([<参数表列>]) [throws <异常类>] { 方法体 } 修饰符: 方法的访问权限(缺省的、public、protected和private) static: 类方法(静态方法); abstract: 抽象方法(无方法体的方法); final: 最终方法(不能被子类改变)。 throws: 表示抛出异常

11 public void setdate(int y,int m,int d) { year=y; month=m; day=d; }
例4.2.2: 日期类的改进版,增加一些方法,便于对数据的操作 public class Date2 { int year,month,day; //设置某一天日期的方法 public void setdate(int y,int m,int d) { year=y; month=m; day=d; } void today( ) { //打印某一天日期的方法 System.out.println("The date of today is "+year+"/“ +month+"/"+day); boolean isleap(int y) { //判断某年是否是闰年的方法 return (y%4==0&y%100!=0)|y%400==0 ;

12 void tomorrow( ) { //计算并打印某天后面一天的日期的方法
int d,m,y; d=day+1;m=month;y=year; if((d>28)&month==2) { if(!isleap(year)|d>29) {d=1;m=m+1;}} else if(d>30&(month<7&month%2==0|month>7 &month%2==1)) {d=1;m=m+1;} else if (d>31) { d=1; m=m+1; if (m==13){y=y+1;m=1;}} System.out.println("The date of tomorrow is "+y+"/"+m+"/"+d); }

13 public static void main(String args[ ]) { Date2 de=new Date2();
de.setdate(2000, 2, 29); if (de.isleap(de.year)) System.out.println(de.year+" is a leap year"); de.today(); de.tomorrow(); } 问题: 类与对象的关系:类是对象的抽象,对象是类的实例化 面向对象程序设计的核心技术: 封装、继承、多态性 类体中包括:变量和方法

14 4.3 对象的创建和使用 创建对象的两种方式: 第一种形式的创建步骤: 第一步: 声明对象 <类名> <对象名> ;
4.3 对象的创建和使用 创建对象的两种方式: 第一种形式的创建步骤: 第一步: 声明对象 <类名> <对象名> ; 第二步: 实例化对象 <对象名>=new <类名>(参数1,参数2,…); 例:Date1 a; //声明对象 a=new Date1( ); //实例化对象

15 <类名> <对象名>=new <类名>(参数1,参数2,…);
第二种创建对象的形式: <类名> <对象名>=new <类名>(参数1,参数2,…); 例:Date2 de=new Date2( ); 实例化就是为对象分配存储空间,并同时对对象进行初始化。这些工作分别用new运算符和类的构造方法( Date2( ))来完成。

16 4.3.2 构造方法和对象的初始化 类的构造方法是一种特殊方法,作用是在创建对象时Java系统调用构造方法去初始化新建对象的成员变量。 例:Date2 de=new Date2( 1999,12,31); 如果没有自定义构造方法,则Java调用类的默认构造方法。Java将使用缺省值(数值为0,对象为null,布尔值为false,字符为‘\0’)来初始化成员变量。 例: Date2 de=new Date2(); 创建自定义构造方法 类的构造方法的名字应该和这个类的名字一样; 构造方法没有返回值(在构造方法名字前连void也不要加)

17 例4.3.1:在类Date2中增加自定义的构造方法 year=y; month=m; day=d; } { }
public class Date2 { int year,month,day; Date2(int y,int m,int d) { //创建构造函数 year=y; month=m; day=d; } Date2() //缺省构造函数 { } //以下同例4.2.2 ………… //以下在main 方法中,调用构造函数对对象进行初始化

18 } public static void main(String args[]) {Date2 de1,de2;
de1=new Date2(1999,3,31); //调用构造函数进行初始化 de2=new Date2(); //调用缺省构造函数 System.out.println("The first object:"); if(de1.isleap(de1.year))System.out.println(de1.year+" is a leap year"); de1.today(); de1.tomorrow(); System.out.println("The second object:"); de2.setdate(2000,2,29); if(de2.isleap(de2.year))System.out.println(de2.year+” is a leap year”); de2.today(); de2.tomorrow();} }

19 无参数的构造方法 如果有自己创建的构造方法,而创建某些对象时又不想进行初始化,一定要在类中创建无参数的构造方法,因为此时已没有缺省的构造方法了。 构造方法是可以重载的 同名但参数不一样的构造方法

20 <对象名> . <变量名>
对象的使用 成员变量的引用格式: <对象名> . <变量名> 例:if(de1.isleap(de1.year))System.out.println(de1.year+" is a leap year"); 成员方法的调用格式: <对象名> . <方法名([参数])> 例: if(de1.isleap(de1.year))System.out.println(de1.year+" is a leap year"); 例:Student.java Student1.java 此处的两个例子用于说明有构造方法和无构造方法的区别.

21 对象的生命周期:对象的创建、使用和销毁这一过程。
4.3.4 对象的消毁 对象的生命周期:对象的创建、使用和销毁这一过程。 对象的销毁:当对象使用完毕后,释放对象所占有的资源(如分配给它的内存)。 对象销毁的方法 Java能自动判断对象是否在使用,并自动销毁不再使用的对象,收回对象所占的资源。 采用finalize()在程序中随时销毁一个对象。 <修饰符> void finalize( ){ 方法体 }

22 static static是一个修饰符,表示与类有关系,而不是与类的某一个对象有关系。 类变量(静态成员变量) 类方法(静态方法)

23 类变量可以被所有的对象共享。在一个对象也没有被创建时,类变量就存在了。当程序运行结束,类变量才被撤消。
 类变量可以被所有的对象共享。在一个对象也没有被创建时,类变量就存在了。当程序运行结束,类变量才被撤消。 引用类变量格式: <类名> . <类变量名> <对象名> . <类变量名> 与实例变量的区别:类变量不管类构造了多少个对象,它只有一份。 例4.4.2

24 类方法(静态方法) 与实例方法的区别: public class UseString{ public static void main(String[] args){ char letter; String str1, str2; str1 = new String(“objects”); if (str1.length() < 10) System.out.println(“Short word: ”+str1); if (str1.length() > 2){ str2= str1.substring(0,2); System.out.println(str1+“ begins with ”+ str2); } public class String{ private char[] data; public static String valueOf(int i){ …} public String(char[] chars){ …} public int length(){ …} public char charAt(int num){ …} public String substring(int ind1, int ind2){ …} } 不创建String的对象,则不能调用String类的length() 或 substring() 方法。

25 你曾经用过的类方法: int a = Integer.parseInt("456"); System.out.println("a: "+a); public class Integer{ public static int parseInt(String s) throws NumberFormatException{ ... } //and many more Integer methods } //end Integer class definition

26 类方法不属于类的某个对象,可以被由该类创建的所有对象使用,也可以被其它类引用。在任何地方都可以使用类方法而不必对类进行实例化操作。
类方法只能引用类变量。 引用类方法格式: <类名> . <类方法名> <对象名> . <类方法名> 例4.4.3 例:使用类方法统计班级的学生成绩 Cnt1.java

27 数学函数类方法 Java类库的Math类库中提供了常用数学函数的类方法: public class Math{
public static int max(int a, int b){...} public static int abs(int a) {...} public static double random(){...} //and many more static Math methods } //end Math class definition Math.max(x,y) Math.abs(a); Math.random(); Math.pow(double x, double y) Math.sqrt(double x) Math.sin(double a); 例:ex_math.java

28 例:用类变量跟踪创建了多少个对象。 public class ProductNumber {
public static int nextID; //class variable 1. private int productID; //instance variable 2. public ProductNumber() { productID = nextID; //3. nextID++; //4. } public int getproductID() { return productID; public static void setInitialID(int num) { nextID = num;

29 public class ProductApp{
public static void main(String[] args){ ProductNumber pNum1, pNum2, pNum3; ProductNumber.setInitialID(1000); //1. pNum1 = new ProductNumber(); //2. pNum2 = new ProductNumber(); pNum3 = new ProductNumber(); System.out.println("pNum1.getproductID(): "+ pNum1.getproductID()); //3. System.out.println("pNum2.getproductID(): "+ pNum2.getproductID()); System.out.println("pNum3.getproductID(): "+ pNum3.getproductID()); System.out.println ("ProductNumber.nextID: "+ProductNumber.nextID); //4 System.out.println("pNum1.nextID: "+ pNum1.nextID); //5 System.out.println("pNum2.nextID: "+ pNum2.nextID); System.out.println("pNum3.nextID: "+ pNum3.nextID); }

30 下列图示表示当application执行到标为//3的行时,内存的情况:
pNum1.getproductID(): 1000 pNum2.getproductID(): 1001 pNum3.getproductID(): 1002 ProductNumber.nextID: 1003 pNum1.nextID: 1003 pNum2.nextID: 1003 pNum3.nextID: 1003 例:student1.java

31 4.4 类的封装 目的: 限制在类的外部对类内部成员进行访问。只通过公共接口来访问类的成员数据。
屏蔽细节。这是程序设计的基本思想方法。便于程序功能的扩展和程序的维护。 访问权限的设置 权 限 同一类 同一包 不同包的子类 所有类 public 允许 protected 不允许 默 认 private

32 类的访问权限的设置 类的权限有两种:默认和public。
如果在一个源程序文件中,声明了若干个类的话,只能有一个类的权限关键字是public。这个类的名字应该和程序文件同名,main方法也应该在这个类中。 例: public class Date{ public static void main(String args[]) { } } class time {

33 public 类的成员的访问权限设置 用权限关键字设置类的成员的权限,以此决定是否允许其类外部的代码访问这些成员。
例: private int year, month, day; public today(); public 被修饰为public的类是公共类,它可供所在包的其他类使用,也可供其他包中的类使用,在程序中可以用import语句引入其他包中的public类。 被public定义的类中成员变量或方法可以供其他类访问。 例: 使用import引入其他包中的public类:Useraccount.java

34 private protected 默认 设置private访问权限,则该类的成员只能被同一类中的成员访问,而不让其他类进行访问。
例:Samp2.java Samp3.java protected 该类的成员可以被同一包中的类或其它包中的该类的子类访问。 默认 默认的权限,该类的成员能被同一包中的类访问。 例: GetNum.java 例4.4.1

35 类的继承 以原有的类为基础创建新的类,从而达到代码复用的目的 被继承的类称为超类(父类)。从超类派生出来(继承超类)的新类称子类。
只支持单重继承,不支持多重继承,所以一个类只能有一个超类。 继承的层次结构。一个子类成为另一个子类的超类。 如果类Sub是类Super的子类,则类Sub继承了超类Super的变量和方法。 子类Sub中,包括两部分的内容:从超类Super中继承下来的变量和方法,自己新增加的变量和方法。 汽车 客车 卡车 轿车 小客车 大客车

36 子类的创建 声明子类 [<修饰符>] class <子类名> extends <超类名> { 子类体 }
如:class Sub extends Super 子类的每个对象也是超类的对象。超类的对象不一定是子类的对象。

37 子类继承超类的成员变量和方法 继承原则: 子类只继承超类中非private的成员变量和方法。 (例见下页) width
例:Shapes.java width height showDim() style area() showStyle() TwoDShape Triangle

38 class TwoDShape{ private double width; private double height; void showDim (){ System.out.println("Width and height are "+width+" and "+height); } class Triangle extends TwoDShape{ String style; double area(){ return width*height/2; // Error! Can’t access void showStyle(){ System.out.println("Triangle is " + style);

39 double getWidth(){return width;} double getHeight(){return height;}
用访问器方法访问类的私有成员:例:shapes2.java double getWidth(){return width;} double getHeight(){return height;} void setWidth(double w){ width=w;} void setHeight(double h){ height=h;} 什么时候应该把实例变量声明为private? 一般坚持两个基本原则:如果一个实例变量只被它所在类中的方法使用,那么应该将其声明为private。如果一个实例变量必须应用在某一个范围内,那么就应该将其声明为private,而且只能通过访问器方法来访问它。这样可以防止把无效的值附给它。

40 变量的隐藏原则:子类的成员变量和超类的成员变量同名时,超类的成员变量被隐藏(不能继承)。
例4.5.1 方法的覆盖原则 子类的成员方法和超类的成员方法同名时,超类的成员方法被子类的成员方法覆盖(不能继承)。 ex7-11

41 “super”关键字 super表示对某个类的超类的引用。 如子类和超类有同名的成员变量或方法,则: super.<成员变量名>
例7-11

42 构造方法的继承 如果子类没有构造方法,则它继承超类无参数的构造方法;如果子类有构造方法,那么在创建子类的对象时,则将先执行继承下来的超类的构造方法,然后再执行自己的构造方法。 对于超类中包含有参数的构造方法,子类可以通过在自己的构造方法中使用super关键字来引用,而且必须是子类构造方法中的第一条语句。 用super调用超类的构造方法:super([参数列表]) 例7-13

43 “null”关键字 基本数据类型的变量有缺省值 类的实例即对象被声明时,它先被初始化为一个特殊的值“null”。这表示它是一个空对象。
int Double 0.0 boolean false

44 检查以下程序的对象是否是null? l1 l2 public class UseLine5{
public static void main(String[] args){ Line l1, l2; l1 = new Line(); if (l1 == null) System.out.println(“l1: “+l1); else System.out.println(“l1 NOT null“); if (l2 == null) System.out.println(“l2: “+l2); System.out.println(“l2 NOT null“); } public class Line{ private int startX, startY; private int endX, endY; public Line() {} public Line(int a,int b,int y,int z){} public int length(){ …} public String toString(){…} public void setStartPt(int x,int y){.} public void setEndPt(int x,int y){} } StartX 0 startY 0 endX 0 endY 0 l1 l2

45 注意不要调用对象的值为null的实例方法。
例: Line line1; line1.setStartPt(10,20); 否则就会产生一个运行错误: java.lang.NullPointerException

46 “This”关键字 在类定义中的方法中需要引用正在使用该方法的对象时,可以用“this”表示。
Line line1 = new Line(); line1.setStartPt(10, 20); 例4.5.3 public void setStartPt(int x,int y){ this.startX = x; //the this can be omitted here this.startY = y; }

47 终止继承 出于安全性方面的考虑,要避免子类继承超类的某个方法,可以使用“final”关键字来使继承终止。 这样使此方法不会在子类中被覆盖(即子类中不能有和此方法同名的方法) 不能被继承的类称为最终类。 如:final class Last; 用final说明的成员方法为最终方法。 如:public final void printsuper( ) 例7-11

48 抽象类和抽象方法 抽象类是专门设计来让子类继承的类。抽象类一般包括一个或多个抽象方法。 抽象方法是必须被子类覆盖的方法。
声明抽象类和方法格式: abstract class <类名> { 成员变量; 方法(){ 方法体 }; //定义一般方法 abstract 方法( ); //定义抽象方法 } 抽象方法不用实现代码,而是在子类中实现所有的抽象方法。 对于成员方法,不能同时用static和abstract说明。对于类,不能同时用final和abstract说明。 例4.5.4

49 类的多态性 多态是指同一个名字的若干个方法,有不同的实现(即方法体中的代码不一样)。
通过方法的重载(overloading)和覆盖(override)来实现多态性。 方法的重载 一个类中,有若干个方法名字相同,但方法的参数不同,称为方法的重载。在调用时, Java只执行方法名、参数个数和参数类型完全相同的方法体。 System.out.println( int ) System.out.println( double ) System.out.println( String ) System.out.println( char )

50 private static void printNumbers(int a, int b){
System.out.println(a + " " + b); } private static void printNumbers(int a, int b, int c){ System.out.println(a + " " + b + " " + c); private static void printNumbers(int a, int b, int c, int d){ System.out.println(a + " " + b + " " + c + " " + d); public static void main(String[] args){ printNumbers(1,2); printNumbers(1,2,3); printNumbers(1,2,3, 4);

51 不正确的方法重载 public void funover(int a,float b) public int funover(int a,float b) 例4.6.1 类的构造方法也可以重载。 例4.3.1 方法的覆盖 在子类和超类中有同名的方法(参数也相同),子类中的方法覆盖超类的方法。 如果超类和子类有同名且参数相同的方法,那么超类的对象调用超类的方法,子类的对象调用子类的方法。 通过覆盖可以使同名的方法在不同层次的类中有不同的实现。

52 接 口 在Java中,一个类只能有一个超类。但Java提供了接口用于实现多重继承,一个类可以有一个超类和多个接口。
接口(interface)是一个特殊的类:由常量和抽象方法组成。 接口的声明 [修饰符] interface <接口名> {接口体} 修饰符:public或默认访问控制。 接口体中的变量隐含为final和static,它们必须被赋初值。如果接口为public,则接口中的变量也是public。 接口体中的方法没有方法体,都是抽象方法。必须在类中实现 。使用public的接口可以被所有的类和接口使用,而默认状态只能被同一包中的其他接口和类使用。 从抽象类和方法引出,例8-1

53 接口的实现 class <类名> implements 接口名1,接口名2,… 一个接口可以被一个或多个类实现。当一个类实现了一个接口,它必须实现接口中所有的方法,这些方法都要被说明为public。否则会产生访问权限错误。 例8-3

54 包 包(package)是类的逻辑组织形式。 Java提供的用于程序开发的类就放在各种包中。也可以自己创建包。 Java的类和包
java.lang 语言包 唯一一个不要把它明确引入程序的包 java.util  实用包 java.awt 抽象窗口工具包 java.text 文本包 java.io 输入输出流的文件包 java.applet Applet应用程序 java.net 网络功能

55 如果要使用Java类中的包,要在源程序中用import语句导入。
导入包 如果要使用Java类中的包,要在源程序中用import语句导入。 import <包名1>[.<包名2>[.<包名3>……]].<类名>|*; 如果有多个包或类,用“.”分割,“*”表示包中所有的类。 如: import java.applet.Applet; //导入Java.applet包中的Applet类 import java.awt.* //导入Java.awt包中所有的类 Java包的路径 用环境变量classpath设置对Java包的搜索路径。切换到DOS方式,用下面命令: set classpath =.; d:\j2sdk1.4.2_02\lib

56 自定义包 如果在程序中没有声明包,类就放在默认的包中,这个包是没有名字的。默认包适用于小的程序,如果程序比较大,就需要创建自己的包。 声明包的格式 package <包名>; 声明一个包的语句要写在源程序文件的第一行。 例: Account.java 存放位置 在运行目录下创建一个和包同名的文件夹(字母大小写也一样),将编译产生的.class文件放到此文件夹中。

57 引用包中的类 如果引用其它包中的类,可用import语句 例:Useraccount.java  包路径的层次结构 包对应于一个文件夹,而类则是文件夹中的一个文件。包路径也可以有层次结构,如: package Firstpackage.package1 用“.”将包的名字分开,形成包路径的层次,package1是Firstpackage文件夹的子文件夹。 Java源程序文件的结构 一个Java的源程序文件依次有以下部分 包的声明语句 包的导入语句 类的声明


Download ppt "第四章 Java面向对象程序设计."

Similar presentations


Ads by Google