1、面向对象程序设计(1),学习目标:,理解类与对象、封装、继承的概念 掌握类中成员变量和方法的声明与使用 掌握对象的创建与使用 理解包的作用与用法 理解抽象类与接口的作用与用法,引言,Java语言作为一种面向对象的程序设计语言,具备面向对象技术的基本属性。 定义类和建立对象是Java编程的主要任务。本章将介绍Java面向对象程序设计的基础,即类、对象、包、接口、类的继承等内容。,面向对象的基本概念,1、 对象的基本概念 对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。,现实世界中的对象有两个共同特征:形态和行为。,软件对象的变量和方法,2. 类,类可以定义为具有类似特征和行为
2、的对象的集合。 如汽车,电视,人。 所有的事物都可以归到某类中。例如,家用电器是一类电子产品。 属于某个类的某一个具体的对象称为该类的一个实例。例如,我的汽车是汽车类的一个实例。 实例与对象是同一个概念。,2、 类的基本概念,类用class作为它的关键字,例如我们要创建一个汽车类,则可表示为:,用类创建对象实例化,当我们要通过汽车类来创建一个轿车对象,并使用它的刹车行为方法时,则要用下面的格式进行实例化:/实例化汽车对象汽车 轿车= new 汽车( ) ; /引用汽车对象的刹车方法轿车.刹车( ) ;,类,类是Java语言的最基本概念,是组成Java程序的基本要素; 类是Java的执行单位,J
3、ava运行的就是Java类本身; 类封装了该类对象的成员变量和方法。当Java程序运行时,系统用类的定义创建类的实例,类的实例是真正的对象。,类的定义,类的定义形式如下: class classname 类成员变量声明;类方法声明; ,public class Teacher private String name;protected int hours;protected long payment;public Teacher(String name,int hours) this.name=name;this.hours=hours;this.payment=0;public void s
4、how()System.out.println(name+“工作了“+hours+“小时,应付“+payment);public void countPayment()payment=counting(1000,hours,50,0); public void resetHour() hours=0; public void addHour(int h) hours+=h; protected long counting(int base,int h,int perHour,long other)return (long)base+h*perHour+other; ,类声明,类声明格式如下:类
5、的修饰字class 类名extends 父类名implements 接口列表 class是声明一个类的关键字,是必须的,类名是要声明的类的名字,它必须是一个合法的Java标识符。 根据声明类的需要,类声明还可以包含三个选项: 声明类的修饰符; 说明该类的父类; 说明该类所实现的接口。,类体,类体用一对大括号括起。 类体中定义了该类中所有的变量和该类所支持的方法: 成员变量对应类的静态属性 方法对应类的行为和操作,成员变量 成员变量是类和对象的静态属性,它可以是基本数据类型的变量,也可以是其它类(系统类或用户自定义类)的对象。 因此,定义成员变量的操作就是说明变量或创建对象的操作。 方法 方法是
6、类的动态属性,标志了类所具有的功能和操作,用来把类和对象的数据封装在一起。 Java的方法与其它语言中的函数或过程类似,是一段完成某种功能的程序段。,成员变量,最简单的成员变量的声明方式如下:type 成员变量名; 这里的type可以是Java中任意的数据结构,包括简单类型、类、接口、数组。 在一个类中的成员变量应该是唯一的。 成员变量的作用域是整个类。,一个具体的类,定义一个类,public class Car String color;float maxSpeed;float currentSpeed;void start() void brake() ,成员方法,方法由方法声明和方法体组
7、成,其一般格式如下: public|protected|privatestaticfinal|abstract返回值类型 方法名(形式参数列表) throws 异常列表方法体各语句; 其中返回类型可以是任意的Java数据类型,当一个方法不需要返回值时,则必须声明其返回类型为void 。 形式参数列表指明每个参数的名字和类型,各参数之间用逗号分隔,格式为:形参类型1 形参名1,形参类型2 形参名2,,class Circleint x,y,radius; /x,y,radius是成员变量public Circle(int x,int y,int radius) /x,y,radius是参数 ,C
8、ircle类有三个成员变量:x、y和radius。 在Circle类的构造函数中有3个参数,名字也是x、y和radius。在方法中出现的x、y和radius指的是参数名,而不是成员变量名。 如果要访问这些同名的成员变量,必须通过“当前对象”指示符this来引用它。,this.x=x; this.y=y; this.radius=radius;,this,this表示的是当前对象本身,更准确地说,this代表当前对象的一个引用。 对象的引用可以理解为对象的另一个名字,通过引用可以顺利地访问到对象,包括访问、修改对象的成员变量、调用对象的方法。,方法体 方法体是对方法的实现。它包括局部变量的声明以
9、及所有合法的Java指令。 方法体中可以声明该方法中所用到的局部变量,它的作用域只在该方法内部,当方法返回时,局部变量也不再存在。 如果局部变量的名字和类的成员变量的名字相同,则类的成员变量被隐藏。,【例】成员变量和局部变量的作用域示例。 class Variableint x=0,y=0,z=0; /类的成员变量void init(int x,int y)this.x=x;this.y=y;int z=5; /局部变量System.out.println(“*in init*“);System.out.println(“x=“+x+“ y=“+y+“ z=“+z); public class
10、 VariableTestpublic static void main(String args)Variable v=new Variable();System.out.println(“*before init*“);System.out.println(“x=“+v.x+“ y=“+v.y+“ z=“+v.z);v.init(20,30);System.out.println(“*after init*“);System.out.println(“x=“+v.x+“ y=“+v.y+“ z=“+v.z); ,方法重载,方法重载即指多个方法可以享有相同的名字。但是这些方法的参数必须不同,或
11、者是参数个数不同,或者是参数类型不同。,【例】方法重载应用举例。class MethodOverloadingvoid receive(int i)System.out.println(“Receive one int data“);System.out.println(“i“+i); void receive(int x,int y)System.out.println(“Receive two int datum“);System.out.println(“x=“+x+“ y=“+y); void receive(double d)System.out.println(“Receive o
12、ne double data“);System.out.println(“d=“+d); void receive(String s)System.out.println(“Receive a string“);System.out.println(“s=“+s); public class MethodOverloadingTestpublic static void main(String args)MethodOverloading mo=new MethodOverloading();mo.receive(1);mo.receive(2,3);mo.receive(12.56);mo.
13、receive(“very interesting,isnt it?“);,构造方法,被自动调用的专门的初始化方法称为构造方法. 构造函数是类的一种特殊方法,其特殊性如下: 构造函数的方法名与类名相同。 构造函数没有返回值。 构造函数的作用是对类的对象初始化。 在创建一个类的新对象的同时,系统会自动调用该类的构造函数。,构造函数是与类同名的方法,创建对象的语句用new运算符开辟了新建对象的内存空间后,将调用构造函数初始化这个新建对象。 一般将构造方法声明为公共的public型,如果声明为private型,那么就不能够创建对象的实例了,因为构造方法是在对象的外部被默认地调用。 Java语言为每一
14、个类提供了一个默认的构造方法,也就是说,每个类都有构造方法,用来初始化该类的一个新的对象。如果不定义一个构造方法,Java语言将调用它提供的默认的构造方法对一个新的对象进行初始化。 在构造方法的实现中,也可以进行方法重载。,【例】构造方法的实现。 class pointint x,y;point( ) /定义构造方法x=0;y=0;point(int x, int y) /构造方法的重载this.x=x;this.y=y;,main( )方法,main( )方法是Java应用程序必须具备的方法。格式是: public static void main(String args) 所有Java的独
15、立应用程序都从main()开始执行。把static放在方法名前就使方法变为静态的方法,即类方法而非实例方法。,对象,对象是类的实例化,对象的创建是通过对象构造方法来实现的; 我们可以生成多个对象,通过消息传递来进行交互,最终完成复杂的任务; 消息传递是指激活指定的某个对象的方法,以改变它的状态或使其产生一定的动作。 一个对象的生命期包括三个阶段:创建、使用和清除。,对象的创建,对象的创建包括声明、实例化和初始化三方面的内容。 一般格式为:type ObjectName=new type(paramlist);type objectName声明了一个类型为type的对象,其中type是引用类型(
16、包括类和接口),对象的声明并不为对象分配内存空间。 运算符new为对象分配内存空间,实例化一个对象。new调用对象的构造方法,返回对该对象的一个引用(即该对象所在的内存地址)。 生成对象的最后一步是执行构造方法,进行初始化。由于对构造方法可以进行重写,所以通过给出不同个数或类型的参数会分别调用不同的构造方法。如果类中没有定义构造方法,系统会调用缺省的空构造函数。,Computer MyComputer=new Computer( ); 等价于: Computer MyComputer; MyComputer=new Computer( ); 其中MyComputer是对象的名称,它是一个属于C
17、oputer类的对象,能够调用Computer类中的set_Owner( )、show_Owner( )方法。,【例】定义类并创建类的对象。 class ComputerString Owner; /成员变量public static void main(String args) void set_Owner(String owner) /成员方法Owner=owner;void show_Owner( )System.out.println(“这台电脑是:“+Owner+“的“); class DemoComputerpublic static void main(String args)S
18、ystem.out.println(“使用类“);Computer MyComputer=new Computer( ); /生成类的对象Mycomputer.set_Owner(“程序设计教研室“);Mycomputer.show_Owner( ); ,对象的使用,要访问或调用一个对象的成员变量或方法,首先访问该对象,然后用成员运算符“.”可以实现对变量的访问和方法的调用。 例如: Mycomputer.set_Owner(“程序设计教研室”); Mycomputer.show_Owner( );,示例,class EmpInfo String name;int salary;String
19、department; void printInfo()System.out.println( name + “ s salary is“ + salary + “ at “ + department); ,实例化一个对象,创建它,然后如下所述对其成员赋值:EmpInfo employee = new EmpInfo(); employee.name = “ 张三”; employee.salary = 5000 ; employee.department = “ 数学学院 ” ; employee.printInfo();,对象的清除,对象的清除,即系统内无用单元的收集。 Java运行时系统
20、通过垃圾收集周期性地释放无用对象所使用的内存,完成对象的清除。 Java采用自动垃圾收集进行内存管理,使程序员不需要跟踪每个生成的对象,这是Java的一大优点。 当下述条件满足时,Java内存管理系统将自动完成收集内存工作。 (1)当堆栈中的存储器数量少于某个特定水平时; (2)当程序强制调用系统类的方法时; (3)当系统空闲时。,存储器的分配,基本数据类型的存储器分配 引用类型的存储器分配,内存分配,内存堆栈区(stack) 总是沿一个方向增长或减少 存放方法或局部变量 内存堆区(heap) 用于存储对象 对象的引用放在堆栈区,而对象的数据放在堆区,void m1() int a1 = 1;
21、Point p1;p1 = new Point(1,2);m2(a1,p1); void m2(int a, Point p) int a2 = 4;Point p2= new Point(3,4);a = 5;,void m1() int a1 = 1;Point p1;p1 = new Point(1,2);m2(a1,p1); void m2(int a, Point p) int a2 = 4;Point p2= new Point(3,4);a = 5;,void m1() int a1 = 1;Point p1;p1 = new Point(1,2);m2(a1,p1); void
22、 m2(int a, Point p) int a2 = 4;Point p2= new Point(3,4);a = 5;,堆栈,堆,封装性与访问控制,封装性,封装性是面向对象的一个重要特征。 在Java语言中,对象就是对一组变量和相关方法的封装体,其中变量表明了对象的状态,方法表明了对象的行为。 通过对象的封装,用户不必了解对象是如何实现的,只须通过对象提供的接口与对象进行交互就可以了。 通过封装性实现了模块化和信息隐藏,有利于程序的可移植性和对象的管理。,封装性的实现,对象的封装通过两种方式实现: (1)通过包实现封装性。在定义类时使用package语句指定类属于哪个包,例如: pack
23、age com.demo; public class Circle 包是Java语言最大的封装单位,它定义了程序对类的访问权限。,包(package),利用Java语言开发实际系统时,可以利用“包”来管理类。包是类和接口的集合,为了方便编程和管理,通常把需要在一起工作的类放在一个包里。 为Java创建一个源码文件的时候,它通常叫做一个“编辑单元”,每个编辑单元必须有一个以java结尾的名字。 缺省情况下,系统为每个.java源文件创建一个无名包,该文件中定义的所有类都隶属于该包,但由于该包无名字,所以不能被其它包引用。为了解决这个问题,就要创建有名包。,包(package),为了便于管理大型软
24、件系统中数目众多的类,解决类命名冲突的问题,Java引入了包(package)。,包(package),package语句必须是文件中的第一条语句。也就是说,在package语句之前,除了空白和注释之外不能有任何语句。 如果不加package语句,则指定为缺省包或无名包。 包对应着文件系统的目录层次结构。 在package语句中,用“.”来指明包(目录)的层次。,包的创建,用package关键字创建包,而且该语句是.java源文件的第一个语句,前面不能有注释和空格。格式为:package 包名; 例如:package SubClass;package MyClass.SubClass; 实际上
25、,创建包就是在当前目录下创建一个子目录SubClass,以便存放这个包中包含的所有类的.class文件。 上面的第二个语句中的“.”代表了目录分隔符。即包中的类放在当前目录下的MyClass 子目录下的SubClass子目录下。,package myclass.graphics; 这条语句指定这个包中的文件存储在目录 path/myclass/graphics 下。,package myclass.graphics; class Square ; class Circle ; class Triangle ;,Square.java,编译和运行包,在前面Square.java中已定义了 myc
26、lass.graphics,编译时可以采用如下方式: javac -d destpath Square.java则编译器会自动在destpath目录下建立子目录myclass/graphics ,并将生成的.class文件都放到destpath/ myclass/graphics下。,包的引用,缺省的情况下,一个类只能引用同一个包中的类,如果需要使用其它包中的public类,可使用如下的方法: 1使用包名、类名前缀 对于同一个包中的其它类,只需在要使用的属性或方法名前加上类名作为前缀,对于其它包中的类,则需要在类名前缀的前面再加上包名前缀。 例如: packageGraphic.Rectang
27、le rectG; java.awt.Rectangle rectA=new java.awt.Rectangle();,2import语句 加前缀的方法使用起来非常麻烦,可以使用import语句加载需要使用的类或包。 import语句的格式为: Import packagel.package2.(classname|*); 其中packagel.package2表明包的层次,与package语句相同,它对应于文件目录,classname则指明所要引入的类。 如果要从一个包中引入多个类,则可以用星号(*)代替。 例如:import java.awt.*; import java.util.Da
28、te;,访问控制符,访问控制符是一组限定类、成员变量或方法是否可以被程序里的其它部分访问和调用的修饰符。 类的访问符只有public。 成员变量和方法的访问控制符有三个: public private protected,类的访问控制符,1公共访问控制符public Java中类的访问控制符只有一个:public,即公共类。一个类被声明为公共类,声明它可以被所有其他类所访问和引用,这里的访问和引用是指这个类作为整体是可见和可使用的。 Java的类是通过包来组织,处于同一包中的类可以不需任何说明而方便的互相访问和引用,而对于处于不同包中的类,缺省的它们是互相之间不可见的。 但是,当一个类被声明为
29、public时,它就具有了被其它包中类访问的可能性,只要这些包中的类在程序中使用import语句引入public类,就可访问它了。 一个类作为整体可见,并不能代表类中的成员变量和方法也一定可见,除非它们也被声明为public。,2.缺省访问控制符 若一个类没有访问控制符,说明它具有缺省的访问控制特性。该访问控制规定这样的类只能被同一个包中的类访问和引用,而不能被其他包中的类使用,这种访问特性又称包访问性。通过声明类的访问控制符可以使整个程序结构清晰、严谨,减少可能产生的类之间的干扰和错误。,私有访问控制符 用private修饰的成员变量或方法只能被该类自身所访问和修改,而不能被任何其它类(包括
30、该类的子类)来获取和引用。 private修饰符提供了最高的保护级别。,class Alphaprivate int iamprivate; / private成员变量private void privateMethod( ) / private成员方法System.out.println(“privateMethod“); class Betavoid accessMethod( )Alpha a=new Alpha( );a.iamprivate=10; /非法a.privateMethod( ); /非法,缺省访问控制符 类中不加任何防问权限限定的成员属于缺省的(default)访问状态
31、,可以被这个类本身和同一个包中的类所访问。这个访问级别是假设在相同包中的类是互相信任的。,package Greek; public class Alphaint iamprivate;void packageMethod( )System.out.println(“packageMethod“); package Greek; class Betavoid accessMethod( )Alpha a=new Alpha( );a.iamprivate=10; /合法a.protectedMethod( ); /合法 ,Alpha类可以访问自己的成员,同时所有定义在与Alpha同一个包中的类
32、也可以访问这些成员。 如Alpha和Beta都定义为Greek包的一部分,则Beta可以合法访问Alpha的成员。,保护访问控制符protected 用protected修饰的成员变量和方法可以被三种类引用: 该类自身; 与它在同一个包中的其它类; 在其它包中的该类的子类。 使用protected修饰符的主要作用是允许包中的类和其它包中的子类来访问父类的特定属性。,公共访问控制符public 被定义为public的方法是这个类对外的接口部分,程序的其它部分通过调用public方法达到与当前类交换信息、甚至影响当前类的目的。 用public修饰的成员变量被称为公共成员变量,如果一个公共成员变量属
33、于一个公共类,则它可被所有其它类所引用。 public修饰符会造成安全性和数据封装性下降,所以一般应减少public成员变量的使用。,对类成员的访问控制,当一个类可以被访问时,对类内的成员变量和成员方法而言,其应用范围可以通过施以一定的访问权限来限定。,访问控制符小结,公共访问控制符(public): public类:公共类,可以被其他包中类引入后访问。 public方法:是类的接口,用于定义类中对外可用的功能方法。 public变量:可以被其他类访问。 缺省访问控制符的类、变量、方法:具有包访问性(只能被同一个包中的类访问)。 私有访问控制符(private):修饰变量或方法,只能被该类自身
34、所访问。 保护访问控制符(protected):修饰变量或方法,可以被类自身、同一包中的类、任意包中该类的子类所访问。,Java类库,为了方便程序设计和运行,Java语言提供了许多类,这些类都是以包的形式组织的。包的数量随着新版本的推出在不断增加,如在JDK 1.0版只有8个包,212个接口和类,到了JDK1.6.0版更是有200多个包。,Java类库简介,Java JDK提供的常用包主要有: java.lang包是Java语言最重要的包,该包中存放着开发Java程序最常用的类。 java.lang包中定义的类主要有:Object类、Class类、Math类、数据类型包装类、String类、
35、StringBuider类、Thread类及Exception类等。 包中还定义了如下几个接口:CharSequence接口、Cloneable接口、Comparable接口和Runnable接口。 使用java.lang包中的类不需要import语句导入,编译器会自动导入该包中的类。,Java类库,java.applet包中只有一个类Applet,是小应用程序的根类。要创建小应用程序需要导入Applet类。 新建的小应用程序应该继承javax.swing包中的JApplet类,但Applet类是JApplet类的父类。 java.awt包中的类与创建图形用户界面的应用程序有关的类,如Butt
36、on、Label等,另外还有一些辅助类,如Color、Font、LayoutManager类等。,Java类库,java.awt.event包中定义了有关事件处理的类和接口。 常用的事件类有ActionEvent、MouseEvent、WindowEvent、KeyEvent等 常用的接口有ActionListener、MouseListener、MouseMotionListener、WindowListener、KeyListener等。 javax.swing包中定义了大量的创建图形用户界面的类。,Java类库,java.io包定义了有关输入输出的类。如InputStream、Outpu
37、tStream、BufferedReader、BufferedWriter、File、RandomAccessFile类等。 包定义了与网络编程有关的类,如URL类、Socket、ServerSocket类等。 java.sql包和javax.sql包中定义了有关数据库编程的类,这些类也称为JDBC API。,Java类库,java.text包中定义了有关文本格式化的类,如DateFormat、NumberFormat类等。 java.util包定义了一些工具类 Date、Calendar、Scanner、Locale类就在这个包中, 还定义了有关数据结构的类、对象集合类,如Collection、List、Set、ArrayList、Stack、HashTable、Vector、Enumeration类等。,