第4课-java面向对象综述二_第1页
第4课-java面向对象综述二_第2页
第4课-java面向对象综述二_第3页
第4课-java面向对象综述二_第4页
第4课-java面向对象综述二_第5页
免费预览已结束,剩余37页可下载查看

下载本文档

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

文档简介

多态

(Polymorphism)

是面 象技术的概念。方法的重写(Overriding)和方法的重载(Overloading)是Java多态性的不同表现。在Java中,子类重写父类方法时,不会隐藏父类中的同名方法。这与C++不同。3.3

接口与动态多态实现一、接口接口(interface)是抽象类概念的进一步深化。接口可以看成是一个完全抽象的类,是一个没有任何实现的类,是抽象方法的集合(可缺省public)。一个类可以implments不止一个接口,这提供了一种实现多重继承的方式。所以接口存在的原因除了与抽象类存在的原因一致外,还可以帮助将一个接口对象

到多个基类。接口中的方法默认是public

的。接口内的变量成员默认是static

和final

的,属于常量。接口与类的不同在于:(1)

没有变量的(2)

只有方法的,但可以定义常量。,没有方法的实现。接口 的基本格式如下:public

interface

接口名extends

接口列表【例4.1】测试接口,定义接口文件Product.java,定义了两个常量, 了一个方法。接口文件如下://程序文件名Product.javapublic

interface

Product{static

final

String

MAKER

=

"计算机制造厂";static

final

String

ADDRESS

=

"

";public

intgetPrice();}使用接口的源文件代码如下://程序文件名UseInterface.javapublic

class

UseInterface{public

static

void

main(String[]

args){Computer

p=new

Computer();System.out.print(p.ADDRESS+p.MAKER);System.out.println("

计算机的价格:"+p.getPrice()+"万元");}}class

Computer

implements

Product{public

intgetPrice(){return

1;}}上例的运行过程是:编译器首先编译接口文件

“Product.java”,然后编译使用这个接口的类文件“UseInterface.java”,最后执行

“UseInterface.class”。如何选择接口和抽象类:接口既提供抽象类的优点也提供接口本身独特的优点,所以应该优先选择接口类,只有需要方法定义和成员变量时才应该考虑将其转化为抽象类。接口应用实例Java实现动态多态主要依赖于接口实现及其回调时的动态绑定过程。一个接口变量可以关联多个实现该接口的类对象。接口变量作为类型,存放其关联对象的引用,那么就可通过接口变量调用对象的接口方法,这个过程称为“回调”。接口回调过程类似于上对象调用子类继承或重写方法的过程。二、动态多态的实现将一个方法调用同一个方法本体关联起来被称作

“绑定(binding)”。“先期绑定”:在编译时编译器就能判断出应该调用的方法称为静态绑定方法。Java中这类方法包括private、static、final方法以及构造方法。“动态绑定“:在运行期由JVM判定对象的类型,并调用其相应的方法称做动态绑定(dynamic

binding)(“后期绑定”、“运行时绑定”)方法。除了静态绑定方法,其他所有的方法都是动态绑定的。这也给多态机制提供了条件。class

A

{static

void

method1()

{System.out.println(“A.method1()”);}void

method2()

{System.out.println(“A.method2()”);}}publicclass

B

extends

A{//

will

not

override

A.method1()static

void

method1()

{System.out.println(“B.method1()”);}//

will

override

the

A.method2()void

method2()

{System.out.println(“B.method2()”);}public

static

void

main(String[]

args)

{A

a=

new

B();a.method1();//A的method1是static,编译时静态绑定,输出

A.method1()a.method2();}//输出

B.method2(),动态绑定体现java的多态性}多态在面 象程序设计中意味着通过动态绑定原理,使用单个变量来

不同类的对象,自动调用

对象类的对应方法。有了动态绑定机制,编译器无需知道对象的类型,但方法的绑定和调用机制能够找出正确的方法体并加以调用。面象的替代原则(substitution

principle):基类可以用其派生类代换。替代过程也是派生类向上的过程。向上是一种常用的安全的类型转换,通过向上也可实现多态性。果园系统的继承与动态多态派生类的对象具有多个类型fruits[0]=new

TropicalFruit("香蕉",1000);fruits[1]=new

Berry("葡萄",2000);fruits[2]=new

TropicalFruit("菠萝",2000);fruits[3]=new

Berry("草莓",1000);fruits[4]=new

CitrusFruit("橘子",1000);动态绑定实现多态

(向上

)可以像对待父类对象那样对待子类对象。即所有继承自共同父类的子类对象可以当做是这些父类的对象。Food

myFood;Fruit

myFruit;CitrusFruit

orange;orange

= new

CitrusFruit("橘子",1000);

//创建橘子对象myFood

=

orange;

//相当于myFood

=

(Food)orange;myFood.eat();

//调用的是CitrusFruit的eat方法:剥皮吃橘子myFruit

=

orange;

//相当于myFruit

=

(Fruit)orange;myFruit.eat();

//调用的还是CitrusFruit的eat方法:剥皮吃橘子4.2

数组、枚举与泛型一、数组在Java中,数组属于

型变量。创建数组需要经过数组

和为数组分配变量两个过程。一维数组创建的语法格式如下:数组类型名称[]

数组变量名;

//

数组变量(也可以写成:数组类型名称数组变量名[];)数组变量名

=

new

数组类型名称[n];

//创建长度为n的数组以上两步也可以合并写为:数组类型名称数组变量名[]=new数组类型名称[n];或者:数组类型名称[]

数组变量名=

new数组类型名称[n];例如:int

score[]

;

//

整型数组scorescore=new

int[3];

//为整型数组score分配内存空间,其元素个数为3或:int

score[]

=

new

int[3];一维数组【例4.2】程序TestJava4_1.java,一维数组的使用方法。public

class

TestJava4_1

{public

static

void

main(String

args[])

{int

i;int

a[];

//a=newint[3];一个整型数组a//为数组a开辟3个内存空间for(i=0;i<3;i++)//输出数组的内容System.out.print("a["+i+"]="+a[i]+",\t");System.out.println("\n数组长度是:"+a.length);}}输出结果:a[0]=

0,a[1]=

0,

a[2]

=

0,数组长度是:3在Java中取得数组的长度(也就是数组元素的个数)可通过“数组名.length”完成。”length”是数组等集合类对象的属性。

如上例中a.length时就给数组赋初值。也可以采用静态方式直接在格式如下:数据类型数组名[]={初值0,初值1,…,初值n}此时编译器根据所给出的初值个数来判断数组的元素个数。除了在 时就赋初值之外,也可以在程序中为某个特定的数组元素赋值。 如:a[0]

=

5;一维数组在Java中提供了许多的API方法。与数组有关的两种常用方法:数组的拷贝操作方法System.arrayCopy(source,0,dest,0,x)功能:

源数组从下标0开始的x个元素到目标数组,从目标数组的下标0所对应的位置开始存取。数组的排序操作Arrays.sort(数组名)一维数组的使用如:for(int

i:a)//a是整形数组System.out.println(i);for(char

ch:b)

//b是字符型数组System.out.println(ch);一维数组的遍历遍历数组,可以使用传统的for循环方式,将循环变量作为索引值 每一个数组元素。也可以使用如下增强型for循环方式遍历数组:for(

循环变量:数组名)目标数组元素类型 变量名二维数组以及数组Java也提供了二维数组以及 数组。二维数组 与分配内存的格式如下:数据类型数组名[][];数组名=new数据类型[行的个数][列的个数];或者:数据类型数组名[][]=new数据类型[行的个数][列的个数];例如:int

score[][]=new

int[4][3];二维数组二维数组的静态赋值格式:数据类型数组名[][]={{第0行初值},{第1行初值},…{第n行初值},};Java允许二维数组中每行的元素个数均不相同。如:int

num[][]={{26,28},{33},{12,34,90}};取得二维数组的行数:数组名.length取得数组中特定行的元素的个数:数组名[索引值].length如:num.length;

//

计算数组num的行数num[0].length

//计算数组num第1行元素个数想要提高数组的维数,只要在

数组的时候将索引与中括号再加一组即可。所以三维数组的

为int

A[][][],而

数组为int

A[][][][]

……,以此类推。二维数组与

数组对象数组对象也可以用数组来存放,通过下面两个步骤来实现:1、

类类型的数组变量,并用new分配内存空间给数组。2、用new产生新的对象,并调用构造方法初始化对象。例如://创建对象数组元p[

]

=

new

[3];素,并分配内存空间for(int

i=0;i<p.length;i++)

{p[i]=new

();}

//对象数组初始化二、枚举类型枚举类型定义包括枚举的

和枚举体。格式如下:[public]

enum

枚举类型名{枚举常量列表}枚举类型是一个类,它的隐含父类是java.lang.Enum。枚举值(枚举常量)是被

的枚举类的自身实例。枚举类不能有public的构造方法,构造方法都隐含private,由编译器自动处理。每个枚举值隐含都是由public、static、final修饰。枚举变量的使用枚举变量只能取枚举常量列表中的枚举值。取值方式:枚举类型名.枚举常量名。如:enum

Season{spring,summer,autumn,winter}Season

x;x=

Season.spring;可以创建枚举类型的一维数组,数组元素依次取枚举常量值。方法如下:枚举类型名数组名[]=枚举类型名.values();枚举变量的使用通过“枚举类型名.values()”取得的枚举常量可以替代一维数组名放入for循环中,遍历每一个枚举常量作为循环条件。方法:for(枚举类型名枚举变量名:枚举类型名.values()){循环体}枚举变量的值也可作为switch语句的判定条件。方法:switch(枚举变量名){case

枚举常量名0:…break;case

枚举常量名1:…break;……}三、泛型泛型也被称为参数化类型,是一种特殊的类型,它把指定类型的工作推客户端代码并实例化类或方法的时候进行。也就是说,在定义类、接口或方法时,可使用泛型参

数,在创建对象或调用方法时,才明确对象或方法的类型。(即编译时不确定类型,运行时确定。)泛型主要作用于集合应用,用于表明集合元素的类型限制。例如需要一个缓冲类Pool来管理等待处理的队列元素,可以使用泛型来取消对Pool所管理元素的具体类型限制,

以增强Pool的功能并降低程序出错风险。泛型类的定义泛型类

方式:[public]

class

泛型类名<T>其中,参数T(或者E)只是个简单字符,用来表示一个未知的类型(注意是类或接口,而非基本类型)。编译类时参数T没有值。在程序运行中具体

并创建实例时,才确定参数T的实际类型。p228例12-1泛型类也是 类型。泛型类的类体内仍然是成员变量或成员方法。类体中方法也可以是泛型方法。泛型接口一个接口也同样可 泛型参数。泛型接口 格式:[public]

interface接口名<T>例如:public

interface

IPool<T>{Tget();int

add(T

t);}

Java

接口规定了不同对象具有相似的行为。泛型进一步扩展了接口的适用范围,可针对不同类型的对象定义相同的行为特征。泛型方法在普通类或者泛型类中,也可以定义泛型方法。通常泛型方法定义为静态方法。例如:public

class

ArrayTool{public

static<E>void

insert(E[]

e,int

i){…}public

static<E>E

value(E[]

e){…}…}方法类型前“<>”中的参数就是方法的泛型参数,可做为方法的返回值和参数的类型

。泛型方法的调用调用泛型方法的格式:(注意是静态方法调用)类名.<返回类型>方法名(实参列表);例如上页例:String[]

names={“

”,“

”};方法insert调用:ArrayTool.insert(names,0);类型为E的value方法调用:ArrayTool.<string>value(names);一个类通过泛型参数定义,实现了处理对象的普遍性。但是由于泛型类的参数只能在运行时被确定类型,限定了泛型类的对象只能做为Object类的实例被处理,无法有效地使用参数实例(泛型类对象)本身提供的方法或属性。解决上述问题需要进行参数类型的边界设定。1、使用extends关键字定义泛型参数的上界格式如下:[public]

class

类名<T

extends

父类名|接口名>泛型参数的限定设定了泛型参数的上界,就可将T类型的对象视为继承的类型,使用所继承的方法和属性。2、使用super关键字定义泛型参数的下界格式如下:集合名<?

super

类名或其超类名>其中,通配符?表示任意类型。而T表示未知类型。通过使用super关键字可以固定泛型参数的类型为某种类型或其某个超类。Java的集合框架在JDK1.2之后,Java提供了实现常见数据结构的类,例如链表类、散列表类等,以便于处理对象集合。这些类被称为集合框架,定义在java.util包中。Java使用泛型的主要目的就是建立具有类型安全的数据结构。从JDK1.5开始,这些实现了的数据结构类均支持泛型,因此在使用过程中不必进行诸如强制类型转换等操作,提高了编译的安全性。LinkedList<E>泛型类LinkedList<E>是实现了泛型接口List<E>的泛型类。用于实现双链表结构的

与操作。(

List<E>是泛型接口Collection<E>的子接口)LinkedList<E>实现的List<E>泛型接口方法:publicboolean

add(Eelement)public

void

add(int

index,E

element)public

void

clear()public

E

remove(int

index)public

boolean

remove(E

element)public

E

get(int

index)public

int

indexOf(E

element)public

int

lastIndexOf(E

element)public

E

set(int

index,E

element):数据替换public

boolean

contains(Objec

ement)public

int

size():返回链表结点个数,即表长(2)LinkedList<E>新增方法:public

void

add (E

element)public

void

addLast(E

element)public

Eget

()public

EgetLast()public

Eremove

()public

EremoveLast()public

Object

clone():克隆当前链表例:创建双链表list。链表数据元素为string类型。LinkedList<string> list=new

LinkedList<string>

();//先创建一个链表对象,表示空双链表list.add(“

o”);list.add(“World!”);//在链表尾增加两个结点遍历链表时可使用集合框架提供的迭代器iterator(),提高对动态 结构对象集合的 速度。p232例12-3Stack<E>泛型类实现堆栈结构的Stack<E>泛型类包含的方法有:public

E

push(E

item)public

E

pop()public

boolean

empty()public

E

peek():取栈顶元素public

int

search(Object

data):获取元素在堆栈中的位置。顶端从1起向下递增。HashMap<K,V>与HashSet<E>HashMap<K,V>泛型类实现哈希表结构的动态与操作(K/V是散列表中 的“键/值”对),实现了Map<K,V>泛型接口。HashMap<K,V>泛型类创建的对象被称作散列

,就是哈希表。 例如创建如下对象:HashMap<string,student>

hatable=HashSet<string,student>();HashMa

温馨提示

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

评论

0/150

提交评论