1、Java程序设计,主讲教师:周立波,2.5 数组2.5.1 数组的声明数组声明的格式:(1)数组类型 数组名(2)数组类型 数组名在数组的声明中不指定数组的长度。例如:int a5 的形式是错误的。2.5.2 数组的创建与初始化1、用new关键字创建数组用new关键字创建数组的格式:new 数组类型size,2、获取数组的过程获得一个数组需要步:第一步,定义数组变量所需的类型第二步,使用new关键字为数组所要存储的数据分配内存空间,并把它们分配给数组变量。int x=new int100;【多学两招】关于内存分配的知识Java把内存划分成两种:一种是栈内存,一种是堆内存。在函数中定义的一些基本
2、类型的变量对象的引用变量都是在栈内存中分配。堆内存用来存放由new创建的对象和数组,在堆中分配的内存由Java虚拟机的自动垃圾回收器来管理。,堆内存栈内存Int x int x = new int100,0x3000 0 x00 x1 . . . .0 x99 New int100 产生的对象,. . .0x3000,3、数组的初始化数组在创建后,其元素是被系统自动进行初始化的。也可以在数组声明中直接给数组赋值。public class TestArraypublic static void main(String args)int x =new int10;for(int i=0;ix.le
3、ngth;i+)System.out.println(“x“+i+“=“+xi);,4、数组的长度Java中为所有数组设置了一个表示数组元素个数的特性变量length。访问该变量可以获取数组的长度:格式为:array.length 5、对象数组例:Person p =new Person10;,第4章 Java面向对象的特性 4.1 概述4.1.1 Java语言的OOP特性1. 封装(Encapsulation)将对象的数据与操作数据的方法相结合,通过方法将对象的数据与实现细节保护起来,就称为封装。外界只能通过对象的方法访问对象,因此封装同时也实现了对象的数据隐藏。在Java语言中,通过类这样
4、的语言机制实现了数据的封装与隐藏。,采用封装的思想保证了类内部数据结构的完整性,应用该类的用户不能轻易直接操纵此数据结构,而只能执行类允许公开的数据。这样避免了外部对内部数据的影响,提高程序的可维护性。,2、继承(inheritance)当一个类是另一个类的特例时,这两个类之间具有的父子关系,我们称之为继承。子类继承了父类的状态和行为,子类还有自身的属性和方法,继承关系减少了程序中相类似代码的重复说明。继承分为单继承和多继承。Java只支持类之间的单继承,多继承实际上是通过接口机制来实现的。,3、多态(polymorphism)将父类对象应用于子类的特征就是多态。换句话说就是“子类的对象指向父
5、类的引用”。多态性允许以统一的风格编写程序,以处理种类繁多的已存在的类以及相关类。该统一风格可以由父类来实现,根据父类统一风格的处理,就可以实例化子类的对象,降低维护的难度。多态的实现并不依赖具体类,而是依赖于抽象类和接口。其含义就是“对外一个接口,对内多种实现”。,4.1.2 Java中类和对象的基本概念类描述了同一类对象具有的数据和行为。创建一个新类相当于创建了一种新的数据类型。 4.2 类的定义4.2.1 类的基本结构类有两种基本成分:成员变量和成员方法。类的成员变量可以是基本类型的数据或数组,也可以是一个类的实例,类的方法处理该类的数据。【注】Java中的方法与其他语言中的函数的区别1
6、、方法只能是类的成员,只能在类中定义。2、调用一个类的成员方法,实际上是对象之间的消息传递。,Java中类定义的基本格式class classname 类的声明 属性声明 构造方法 类体 成员方法 1、类的声明类的完整声明格式: publicabstractfinal class classname extends Superclassimplements Interface,public指明任意类都可以访问这个类。(如果类声明中没有public,则只有与该类定义在同一个保中的类才可以访问这个类。)abstrac指明该类是个抽象类。final指明该类是个最终类,不能再派生子类。 extends
7、 Superclass指明该类所继承的父类。implements Interfaces指明该类所实现的接口。2、类体3、类的封装与信息隐藏,类的封装与信息隐藏,是具体通过对类的成员限定访问权限来实现的。Java中规定的类的成员访问权限有四种:public、protected、private及默认权限。public成员可以被所有的类访问。private成员只能被这个类本身访问protected成员可以被这个类本身、它的子类以及同一个保重的所有其它类所访问。类的封装与信息隐藏机制:使用privtae权限将类的内部数据隐藏起来,只允许类自身的方法对其操作,然后通过public/protected权限
8、将方法作为类的接口裸露出来,使外界只能通过这些接口访问类的数据,从而实现了类的封装,同时也最大限度隐藏了对象的内部细节。,4.2.2 成员变量public|protected|privatestaticfinal type variable 4.2.3 成员方法1、成员方法的定义(1)方法的声明public|protected|privatestaticfinal|abstractreturnType name (list) throws block ,(2)方法体【注】方法体中所声明以及用到的局部变量,它的作用域只在该方法内部。如果局部变量的名字和类成员变量的名字相同,则类成员变量被隐藏,如
9、果要将类成员变量显露出来,则需要在变量前加上“this”关键字修饰符。 4.2.4 方法重载方法重载允许一个类的定义中,多个方法使用相同的方法名。方法重载是面向对象程序语言多态性的一种表现。它实现了Java编译时多态。,public class TestOverloadingpublic int add(int x, int y) return x+y; public int add( int x, int y, int z) return x+y+z; public double add(double x,double y) return x+y; public static void ma
10、in(String args) int isum; double fsum;isum=add(3,5);isum=add(1,3,5);fsum=add(1.23 , 2.3); ,方法重载必须遵循的原则:方法的参数表必须不同。方法的返回值、修饰符可以相同也可以不同 4.2.5 this关键字this是一个特定意义的引用,它指向当前对象本身。 4.3 构造函数4.3.1 构造函数的定义与作用构造函数的特点:构造函数的名称必须与类名相同构造函数不能有返回值用户不能直接调用构造方法,必须通过new关键字自动调用构造方法。,例子:this使用示例public class MyDateprivate
11、int day, month, year;public MyDate(int day, int month, int year) this.day=day;this.month=month;this.year=year; public String tomorrow()this.day=this.day+1;return this.day+”/”+this.month+”/”+this.year; public static void main(String args)MyDate d=new MyDate(12,4,2004);System.out.println(d.tomorrow();
12、 ,构造函数的作用:构造函数可以为类的成员变量进行初始化当一个类的实例对象刚产生时,这个类的构造方法就会被自动调用,我们可以在这个方法中加入要完成初始化工作的代码4.3.2 缺省的构造方法用缺省的构造方法初始化对象时,由系统用默认值初始化对象的成员变量各种数据类型的默认值为:数值型: Boolean: false 对象:null,class Personpublic Person()System.out.println(“bath me”);private int age=10;public void shout()System.out.println(“Im ”+age+”years old
13、”); public class TestPersonPerson p1=new Person();p1.shout();Person p2=new Person();p2.shout(); ,4.3.3 重载构造方法构造方法可以重载,即定义多个构造方法,其参数表不同。重载构造方法的目的是使对象具有不同的初始值,为类对象的初始化提供方便。4.4 对象的生命周期一个Java程序将包含很多对象,这些对象通过发送消息彼此进行交互操作,实现了Java程序的各种功能。当一个对象完成了所有操作后,将被垃圾回收器收回,它所占有的资源将被回收并由系统提供给其他对象使用。对象的生命周期包括了对象的创建、对象的使
14、用和对象回收几个阶段。,4.4.1 对象的创建1、对象创建的过程创建一个对象包括两个步骤:(1)声明对象变量对象变量的声明,使得系统为该变量分配了一个引用空间(栈内存)。(2)对象的实例化通过使用new关键字进行对象的实例化。对象实例化的过程是为对象分配内存空间(堆内存),执行new关键字后的构造方法完成对象的初始化,并返回该对象的引用。,2、创建与初始化对象的过程对象创建与初始化,即执行new Class()的过程如下:(1)首先为对象分配内存空间,并将成员变量进行初始化:数值型变量的初值为0;逻辑性为false;引用型变量的初值为null。(2)然后执行显式初始化,即执行在类成员变量声明时
15、带有的简单赋值表达式。(3)执行构造方法,进行对象的初始化。,4.4.2 对象的使用(访问)通过原点运算符( )可以访问对象的变量和方法.访问对象的变量 注不提倡对对象变量的直接访问.好的对象变量访问方式是通过对象提供的setter和getter方法对变量进行写和读.调用对象的方法对象名.方法 ( ) 4.4.3 对象的清除在Java中,采用垃圾回收器来进行内存管理.Java运行系统会在确定某个对象不再被使用时自动将其删除.垃圾回收器回收的对象是被确定不存在任何引用的对象.不存在引用包括两种情况:引用超过其作用域;引用被显式删除.,4.4.4 对象的比较在Java语言中有两种对象的比较方式,分
16、别为“=”和equals()方法。equals()方法是String类中的方法,它用于比较两个对象所指的内容是否相等;而“=”运算符比较的时两个对象引用的地址是否相等。,4.5 类的继承 4.5.1 类的继承1. 子类及其定义子类声明的具体格式如下:class SubClass extends SuperClass 类体子类可以继承父类的属性和方法,子类只需声明自己特有的东西.子类不能继承父类的包括: 带private修饰符的方法和属性 构造方法不能被继承,2. 单继承Java只支持单继承,单继承的优点是可以避免多个直接父类之间可能产生的冲突.对于现实中的多重继承,Java是通过接口机制实现.
17、 3. 继承性的特点(1)通过继承可以简化类的定义。(2)Java只支持单继承,不允许多重继承。(3)可以有多层继承,即一个类可以继承某一个类的子类。(4)子类继承父类所有的成员变量和方法,但不继承父类的构造方法,如果要在子类的构造方法中调用父类的构造方法,可以使用super关键字来。,Super关键字的用法super关键字用来在子类中引用父类中的成员或构造方法.使用super调用父类的构造方法格式:super(Parameter-list)使用super访问被子类成员隐藏的父类成员格式:super.method(parameter-list);super.attribute;,4.5.2 方
18、法的重写(overriding)重写与重载是两个不同的概念.1.字类中父类成员的隐藏 在类的层次结构中,当子类的成员变量与父类的成员变量同名时,子类的成员变量会隐藏父类的成员变量.当子类的方法与父类的方法具有相同的名字、参数列表、返回值类型时,子类的方法重写了父类的方法,父类的方法就被隐藏.“隐藏”的含义是,通过子类对象调用子类中与父类同名的变量和方法时,操作的是这些变量和方法在子类中的定义.,2.方法重写脚下当心子类可以改写父类方法所实现的功能,但子类中重写的方法必须与父类中对应的方法具有相同的返回值、方法名和参数列表.3.方法重写遵守的原则子类中重写方法的返回值类型必须与父类中被重写方法的
19、返回值类型相同.子类中重写方法的访问权限不能缩小.子类中重写父类的方法时不能抛出异常.,4.5.3 抽象类1、抽象类的定义只有声明而没有方法体的方法称为抽象方法,包含一个或多个抽象方法的类称为抽象类。关于抽象类的讨论:抽象类和抽象方法必须用abstract关键字来修饰。抽象方法只需声明,而不需实现。抽象类不能被实例化,也就是不能用new关键字产生对象。含有抽象方法的类必须被声明为抽象类,抽象类的子类必须覆盖所有的抽象方法后才能被实例化,否则这个子类还是个抽象类。,2、抽象方法、抽象类的格式abstract class A abstract int aa( int x ,int y ) ; 4.
20、5.4 接口(Interface)1、什么是接口接口是抽象方法和常量值的定义的集合。从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。,2、接口的定义接口的定义包括接口声明和接口体两部分。(1)接口声明:public interface name extends SuperInterface. body 【注】public指明任意类可以使用这个接口。默认情况下,只与该接口定义在同一个包中的类可以访问这个接口。 (2)接口体接口体中包含常量定义和方法定义,3、接口的实现与使用在类的声明中用implements子句来表示一个类实现了某个接口,在类体中可
21、以使用接口中定义的常量,而且必须实现接口中定义的所有方法。一个类可以实现多个接口,在implements子句中用逗号格开。【注】在类中实现接口所定义的方法时,方法的声明必须与接口中所定义的完全一致。【小结】实现接口:实现一个接口就是要实现该接口的所有方法(抽象类除外)。接口中的方法都是抽象的。多个无关的类可以实现同一个接口,一个类可以实现多个无关的接口。,4.5.5 多重继承C+Z中的多重继承用以引起代码冲突。而Java中类只能进行单继承,其多重继承是利用接口机制来实现的。4.5.6 通过继承来扩展接口接口也是可以继承的,利用extends关键字来进行接口的继承。从而实现接口的扩展。4.5.7
22、接口与抽象类的区别 接口中的所有方法都是抽象的,而抽象类可以定义带有方法体的不同方法。, 一个类可以实现多个接口,单只能继承一个抽象父类。 接口与实现它的类不构成类的继承体系,即接口不是类体系的一部分。而抽象类是属于一个类的继承体系,并且一般位于类体系的顶层。,【包装类】Java中的类把方法与数据连接在一起,并构成了自包含式的处理单元。但在Java中不能定义基本类型对象,为了能将基本类型视为对象来处理,并能连接相关的方法,Java为每个基本类型都提供了包装类,这样我们就可以把这些基本类型转换为对象来处理了。常用的包装类有:Integer、Long、Short、Boolean、Byte、Char
23、acter、Double、Float。,第五章 Java高级特征 5.1 static关键字static修饰的变量或方法称为类变量和类方法。1. 静态变量/类变量在类中,用static修饰符修饰的变量成为类变量或静态变量。静态变量只在系统加载其所在类时分配空间并初始化,并且在创建类的实例时将不再分配空间,所有的实例将共享类的静态变量。静态变量是在一个类中所有的实例对象都可以访问的变量,静态变量依附于类,而与类的实例对象无关,所以对于不是private类型的静态变量,我们可以在该类外直接用类名调用,而不需实例化。,2、静态方法在类的成员方法声明种带有static关键词,则该方法就称为类方法或静态
24、方法。静态方法要通过类名而不是通过实例对象访问。【脚下留心】(1)在静态方法里只能直接调用同类中其他的静态成员,而不能直接访问类中的非静态成员。(2)子类不能重写父类的静态方法,但在子类中可以声明与父类静态方法相同的方法,从而将父类的静态方法隐藏。另外,子类不能把父类的非静态方法重写为静态的。,3、静态代码块一个类中可以使用不包含在任何方法体中的静态代码块,当类被载入时,静态代码块被执行,而且只被执行一次,静态块经常用来进行类属性的初始化。4.理解main方法的语句public static void main(String a )由于Java虚拟机需要调用类的main方法,所以该方法的访问权
25、限必须是public.又因为Java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static 的.该方法接收一个String类型的数组参数,该数组中保存执行Java命令时传递给所运行的类的参数。,public class TestMainpublic static void main(String args)for(int i=0; iargs.length; i+)System.out.println( argsi );,5.2 final关键词1、在类的声明中使用final被定义成final的类不能再派生子类。2、在成员方法声明中使用final被定义成final的方法不能被
26、重写。3、在成员变量的声明中使用final如果类的成员变量被定义成final,则变量一经赋值就不能改变,所以可以通过声明final变量并同时赋初值来定义常量。【注】如果在程序中要改变final变量的值,则将产生编译时错误。,5.5 包5.5.1 什么是包将一组相关的类和接口包裹在一起形成包,包是OOP的封装性的一种体现.包的引入为Java提供了以包为单位的独立命名空间,有效地解决了命名冲突的问题.它是相关类与借口的一个集合,它提供了类的命名空间的管理和访问保护.每个包中都定义了许多功能相关的类和接口,我们也可以定义自己的包来实现自己的应用程序.使用包机制的好处是:程序员容易确定包中的类是相关的
27、,并且容易根据所需的功能找到相应的类。,每个包都创建一个新的命名空间,因此不同包中的类是不相关的. 同一个包中的类之间有比较宽松的访问控制. 5.5.2 包的定义与使用1、包的定义使用package语句指定一个源文件中的类属于一个特定的包。Package语句的格式:package pk1.pke.pk3;【说明】:package语句在每个Java源程序中只能有一条,一个类只能属于一个包。,package语句必须在程序的第1行。包名以“ ”为分隔符。2、包成员的使用包中的成员是指包中的类和接口。访问包成员有两种方式: 引入包成员或整个包,然后使用短名(类名或接口名)引用包成员。 使用长名(由包名
28、与类/接口名组成)引用包成员。(1)引入包成员在Java中引入包中的类是通过import语句实现的。,Import语句的格式如下:import pk1.pk2.pk3(classname | *) ;包的层次 要引入的类 引入包中多个类【注】import语句必须在源程序任何类声明之前,在package语句之后。所以Java程序的一般结构如下:package语句;import语句;类声明(2)使用长名引用包成员当要在程序中使用其他包中的类,而该包并没有引入,则必须使用长名引用该类。长名的格式: 包名.类名,Classpath环境变量classpath环境变量是设置指向顶层包名所对应目录的父目录,
29、而不是指向.class文件所在的目录。【注】1、即使文件名相同,但其中所包含的类的完整名称却不一定相同。2、同一个包中的类不必位于同样的目录。,3.包定义与使用示例 5.5.3 包名与包成员的存储位置Java中包名实际上是包的存储路径的一部分,包名中的 分隔符相当于目录分隔符。包存储的路径实际上由包的根路径加上包名指明的路径组成,而包的根路径由CLASSPATH环境变量指出。 5.5.4 Java源文件与类文件的管理一般原则:(1)在应用系统目录下分别创建源文件目录与类文件目录,并把类文件目录加入到classpath环境变量中。,(2)每个源文件都存放在source目录中以包名为相对路径的子目
30、录中,编译后产生的类文件以所属包名为相对路径,存储在class目录下。 5.5 访问控制1、访问控制概述Java中,我们可以在类的定义中使用权限修饰符来保护类的变量和方法。Java支持四种不同的访问权限:private、protected、public、default。对于类的成员变量和方法可以定义上述四种访问级别,对于类可以有public和default两种。,同一个类 同一个包 子类private yes no no Default yes yes no Protected yes yes yes public yes yes yes 四种修饰符的作用范围,2、private 类中带有pr
31、ivate的成员只能被这个类自身访问。【注】若讲构造方法限定为private,则其他类不能生成该类的实例对象。【注】同一个类的不同对象之间可以访问对方的private成员变量和方法。3、defaultdefault权限意味这可以被这个类本身和同一个包中的类所访问。4、protectedprotected权限表示该成员可以被这个类本身、它的子类以及同一个包中所有其他类访问。,5.3 Object类Object类是Java平台中类层次树的跟,Java中的每个类都是Object类的直接或间接子类。Object类中定义了所有对象都需要的状态和行为,例如对象间的比较,将对象转换为字符串等等。在Objec
32、t子类中,可以重写一下Object类的方法:clone() ,equals(), finalize(), toString()。clone()方法:从一个对象复制另一个对象。equals()方法:比较当前对象的引用是否与参数obj指向同一个对象。toString()方法:返回对象的字符串表示。getClass()方法:返回对象的类信息。,5.4 对象的多态性对象类型转换1.子类转换成父类子类能够自动转换成父类类型。我们称这种转换为上溯造型,Java中允许上溯造型的存在。上溯造型中,父类类型的变量可以指向子类对象,但通过该变量只能访问父类中定义的变量和方法,子类特有的方法不能访问。2.父类转换成
33、子类对象的强制类型转换也称为向下造型,是将父类类型的对象变量强制(显式)地转换为子类类型。,在强制类型转换时,我们要对转换完的后果负责,要确保在内存中存在的对象本身可以被看成那种要转换成的类型。3.instanceof操作符可以用instanceof判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类。语法格式:对象 instanceof 类(接口)表达式的返回值是boolean型的,Public static void callA(A a)if(a instanceof B)B b=(B)a;b.func1();b.func2();b.func3();elsea.func
34、1();a.func2();,5.5 内部类1.内部类的概念内部类是在一个类的声明里声明的类,也称为嵌套类。class Aclass BB称为内部类,类A称为B的包容类或外包类。2.内部类的使用,(1) 内部类可以作为外包类的一个成员使用,可以访问外包类的所有成员 (2) 在外包类的语句块中定义内部类内部类可以在一个方法体的语句块中定义。这时内部类可以访问语句块中的局部变量,但只限于在该语句块运行期,当该方法运行结束后,内部对象将不能访问所在语句块中的局部变量。另外,这样的内部类只能用于在定义它的语句块中创建该内部类的对象,而且内部类的类名也不能出现在定义它的语句块之外。,(3)在外包类以外的
35、其他类中访问内部类Java中,内部类的访问权限与普通类和接口不同,可以定义为public,protected,default或private,而普通类只能定义public或default两种。对于可以在外包类之外的内部类,引用内部类名时必须使用完整的标识:外包名.内部类名。并且在创建内部类对象时,必须与外部类的对象相关。2、内部类的特性内部类的类名只用于定义它的类或语句块之内,在外部引用它时必须给出带有外包类名的完整名称,并且内部类的名称不许与外包类的名称相同。内部类可以访问外包类的静态或实例成员变量。,内部类可以在成员方法中定义,该成员方法的局部变量及参数必须是final的才能被该内部使用。内部类可以是抽象类或接口。如果是接口,则可以由其他内部类实现。内部类可以使用public、protected、default或private等4种权限控制。内部类可以被声明为static(普通类不可以),这样的内部类变成顶层类,相当于把它放在外面,不再是嵌套的内部类,并且它的对象中将不包含指向外包类对象的指针,所以不能再引用外包类对象。只有顶层类可以声明static成员。,