java的特征及多态.docx
《java的特征及多态.docx》由会员分享,可在线阅读,更多相关《java的特征及多态.docx(25页珍藏版)》请在冰点文库上搜索。
java的特征及多态
3.1.2面向对象的基本特征
1.封装性
封装性就是把对象的属性和服务结合成一个独立的相同单位,并尽可能隐蔽对象的内部细节,包含两个含义:
◇把对象的全部属性和全部服务结合在一起,形成一个不可分割的独立单位(即对象)。
◇信息隐蔽,即尽可能隐蔽对象的内部细节,对外形成一个边界〔或者说形成一道屏障〕,只保留有限的对外接口使之与外部发生联系。
封装的原则在软件上的反映是:
要求使对象以外的部分不能随意存取对象的内部数据(属性),从而有效的避免了外部错误对它的"交叉感染",使软件错误能够局部化,大大减少查错和排错的难度。
2.继承性
特殊类的对象拥有其一般类的全部属性与服务,称作特殊类对一般类的继承。
例如,轮船、客轮;人、大人。
一个类可以是多个一般类的特殊类,它从多个一般类中继承了属性与服务,这称为多继承。
例如,客轮是轮船和客运工具的特殊类。
在java语言中,通常我们称一般类为父类(superclass,超类),特殊类为子类(subclass)。
3.多态性
对象的多态性是指在一般类中定义的属性或服务被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。
这使得同一个属性或服务在一般类及其各个特殊类中具有不同的语义。
例如:
"几何图形"的"绘图"方法,"椭圆"和"多边形"都是"几何图"的子类,其"绘图"方法功能不同。
3.1.3面向对象程序设计方法
OOA-ObjectOrientedAnalysis 面向对象的分析
OOD-ObjectOrientedDesign 面向对象的设计
OOI-ObjectOrientedImplementation 面向对象的实现
3.2Java语言的面向对象特性
3.2.1类
类是java中的一种重要的复合数据类型,是组成java程序的基本要素。
它封装了一类对象的状态和方法,是这一类对象的原形。
一个类的实现包括两个部分:
类声明和类体。
1.类声明:
[public][abstract|final]classclassName[extendssuperclassName][implementsinterfaceNameList]
{……}
其中,修饰符public,abstract,final说明了类的属性,className为类名,superclassName为类的父类的名字,interfaceNameList为类所实现的接口列表。
2.类体
类体定义如下:
classclassName
{[public|protected|private][static]
[final][transient][volatile]type
variableName; //成员变量
[public|protected|private][static]
[final|abstract][native][synchronized]
returnTypemethodName([paramList])[throwsexceptionList]
{statements} //成员方法
}
3.成员变量
成员变量的声明方式如下:
[public|protected|private][static]
[final][transient][volatile]type
variableName; //成员变量
其中,
static:
静态变量(类变量);相对于实例变量
final:
常量
transient:
暂时性变量,用于对象存档
volatile:
贡献变量,用于并发线程的共享
4.成员方法
方法的实现包括两部分内容:
方法声明和方法体。
[public|protected|private][static]
[final |abstract][native][synchronized]
returnTypemethodName([paramList])
[throwsexceptionList] //方法声明
{statements} //方法体
方法声明中的限定词的含义:
static:
类方法,可通过类名直接调用
abstract:
抽象方法,没有方法体
final:
方法不能被重写
native:
集成其它语言的代码
synchronized:
控制多个并发线程的访问
◇方法声明
方法声明包括方法名、返回类型和外部参数。
其中参数的类型可以是简单数据类型,也可以是复合数据类型(又称引用数据类型)。
对于简单数据类型来说,java实现的是值传递,方法接收参数的值,但不能改变这些参数的值。
如果要改变参数的值,则用引用数据类型,因为引用数据类型传递给方法的是数据在内存中的地址,方法中对数据的操作可以改变数据的值。
例3-1说明了简单数据类型与引用数据的区别。
【例3-1】
importjava.io.*;
publicclassPassTest{
floatptValue;
publicstaticvoidmain(Stringargs[]){
intval;
PassTestpt=newPassTest();
val=11;
System.out.println("OriginalIntValueis:
"+val);
pt.changeInt(val); //值参数
System.out.println("IntValueafterChangeis:
"+val);/*值参数
值的修改,没有影响值参数的值*/
pt.ptValue=101f;
System.out.println("OriginalptValueis:
"+pt.ptValue);
pt.changeObjValue(pt);//引用类型的参数
System.out.println("ptValueafterChangeis:
"+pt.ptValue);/*引用参数值的修改,改变了引用参数的值*/
}
publicvoidchangeInt(intvalue){
value=55; //在方法内部对值参数进行了修改
}
publicvoidchangeObjValue(PassTestref){
ref.ptValue=99f; //在方法内部对引用参数进行了修改
}
}
运行结果c:
\>javaPassTest
OriginalIntValueis:
11
IntValueafterChangeis:
11
OriginalptValueis:
101.0
ptValueafterChangeis:
99.0
◇方法体
方法体是对方法的实现,它包括局部变量的声明以及所有合法的Java指令。
方法体中声明的局部变量的作用域在该方法内部。
若局部变量与类的成员变量同名,则类的成员变量被隐藏。
例3-2说明了局部变量z和类成员变量z的作用域是不同的。
【例3-2】
importjava.io.*;
classVariable{
intx=0,y=0,z=0; //类的成员变量
voidinit(intx,inty){
this.x=x;this.y=y;
intz=5; //局部变量
System.out.println("**ininit**");
System.out.println("x="+x+"y="+y+"z="+z);
}
}
publicclassVariableTest{
publicstaticvoidmain(Stringargs[]){
Variablev=newVariable();
System.out.println("**beforeinit**");
System.out.println("x="+v.x+"y="+v.y+"z="+v.z);
v.init(20,30);
System.out.println("**afterinit**");
System.out.println("x="+v.x+"y="+v.y+"z="+v.z);
}
}
运行结果
c:
\>javaVariableTest
**beforeinit**
x=0y=0z=0
**ininit**
x=20y=30z=5
**afterinit**
x=20y=30z=0
上例中我们用到了this,这是因为init()方法的参数名与类的成员变量x,y的名字相同,而参数名会隐藏成员变量,所以在方法中,为了区别参数和类的成员变量,我们必须使用this。
this-----用在一个方法中引用当前对象,它的值是调用该方法的对象。
返回值须与返回类型一致,或者完全相同,或是其子类。
当返回类型是接口时,返回值必须实现该接口。
5.方法重载
方法重载是指多个方法享有相同的名字,但是这些方法的参数必须不同,或者是参数的个数不同,或者是参数类型不同。
返回类型不能用来区分重载的方法。
参数类型的区分度一定要足够,例如不能是同一简单类型的参数,如int与long。
【例3-3】
importjava.io.*;
classMethodOverloading{
voidreceive(inti){
System.out.println("Receiveoneintdata");
System.out.println("i="+i);
}
voidreceive(intx,inty){
System.out.println("Receivetwointdatas");
System.out.println("x="+x+"y="+y);
}
}
publicclassMethodOverloadingTest{
publicstaticvoidmain(Stringargs[]){
MethodOverloadingmo=newMethodOverloading();
mo.receive
(1);
mo.receive(2,3);
}
}
运行结果(编译器会根据参数的个数和类型来决定当前所使用的方法)
c:
\>javaMethodOverloadingTest
Receiveoneintdata
i=1
Receivetwointdatas
x=2y=3
6.构造方法
◇构造方法是一个特殊的方法。
Java中的每个类都有构造方法,用来初始化该类的一个对象。
◇构造方法具有和类名相同的名称,而且不返回任何数据类型。
◇重载经常用于构造方法。
◇构造方法只能由new运算符调用
【例3-4】
classPoint{
intx,y;
Point(){
x=0;y=0;
}
Point(intx,inty){
this.x=x;
this.y=y;
}
}
3.2.2对象
类实例化可生成对象,对象通过消息传递来进行交互。
消息传递即激活指定的某个对象的方法以改变其状态或让它产生一定的行为。
一个对象的生命周期包括三个阶段:
生成、使用和消除。
1.对象的生成
对象的生成包括声明、实例化和初始化。
格式为:
typeobjectName=newtype([paramlist]);
◇声明:
typeobjectName
声明并不为对象分配内存空间,而只是分配一个引用空间;对象的引用类似于指针,是32位的地址空间,它的值指向一个中间的数据结构,它存储有关数据类型的信息以及当前对象所在的堆的地址,而对于对象所在的实际的内存地址是不可操作的,这就保证了安全性。
◇实例化:
运算符new为对象分配内存空间,它调用对象的构造方法,返回引用;一个类的不同对象分别占据不同的内存空间。
◇生成:
执行构造方法,进行初始化;根据参数不同调用相应的构造方法。
2.对象的使用
通过运算符"."可以实现对变量的访问和方法的调用。
变量和方法可以通过设定访问权限来限制其它对象对它的访问。
◇调用对象的变量
格式:
objectReference.variable
objectReference是一个已生成的对象,也可以是能生成对象的表达式
例:
p.x=10;
tx=newPoint().x;
◇调用对象的方法
格式:
objectReference.methodName([paramlist]);
例如:
p.move(30,20);
newPoint().move(30,20);
3.对象的清除
当不存在对一个对象的引用时,该对象成为一个无用对象。
Java的垃圾收集器自动扫描对象的动态内存区,把没有引用的对象作为垃圾收集起来并释放。
System.gc();
当系统内存用尽或调用System.gc()要求垃圾回收时,垃圾回收线程与系统同步运行。
3.2.3面向对象特性
java语言中有三个典型的面向对象的特性:
封装性、继承性和多态性,下面将详细阐述。
1.封装性
java语言中,对象就是对一组变量和相关方法的封装,其中变量表明了对象的状态,方法表明了对象具有的行为。
通过对象的封装,实现了模块化和信息隐藏。
通过对类的成员施以一定的访问权限,实现了类中成员的信息隐藏。
◇类体定义的一般格式:
classclassName
{ [public|protected|private][static]
[final][transient][volatile]type
variableName; //成员变量
[public|protected|private][static]
[final|abstract][native][synchronized]
returnTypemethodName([paramList])
[throwsexceptionList]
{statements}//成员方法
}
◇java类中的限定词
java语言中有四种不同的限定词,提供了四种不同的访问权限。
1)private
类中限定为private的成员,只能被这个类本身访问。
如果一个类的构造方法声明为private,则其它类不能生成该类的一个实例。
2)default
类中不加任何访问权限限定的成员属于缺省的(default)访问状态,可以被这个类本身和同一个包中的类所访问。
3)protected
类中限定为protected的成员,可以被这个类本身、它的子类(包括同一个包中以及不同包中的子类)和同一个包中的所有其他的类访问。
4)public
类中限定为public的成员,可以被所有的类访问。
表3-1列出了这些限定词的作用范围。
【表3-1】 java中类的限定词的作用范围比较
同一个类同一个包不同包的子类不同包非子类
private*
default**
protected***
public****
2.继承性
通过继承实现代码复用。
Java中所有的类都是通过直接或间接地继承java.lang.Object类得到的。
继承而得到的类称为子类,被继承的类称为父类。
子类不能继承父类中访问权限为private的成员变量和方法。
子类可以重写父类的方法,及命名与父类同名的成员变量。
但Java不支持多重继承,即一个类从多个超类派生的能力。
◇创建子类
格式:
classSubClassextendsSuperClass{
…
}
◇成员变量的隐藏和方法的重写
子类通过隐藏父类的成员变量和重写父类的方法,可以把父类的状态和行为改变为自身的状态和行为。
例如:
classSuperClass{
intx;…
voidsetX(){x=0;}…
}
classSubClassextendsSuperClass{
intx; //隐藏了父类的变量x
…
voidsetX(){//重写了父类的方法setX()
x=5;}….
}
注意:
子类中重写的方法和父类中被重写的方法要具有相同的名字,相同的参数表和相同的返回类型,只是函数体不同。
◇super
java中通过super来实现对父类成员的访问,super用来引用当前对象的父类。
Super的使用有三种情况:
1)访问父类被隐藏的成员变量,如:
super.variable;
2)调用父类中被重写的方法,如:
super.Method([paramlist]);
3)调用父类的构造函数,如:
super([paramlist]);
【例3-5】
importjava.io.*;
classSuperClass{
intx;
SuperClass(){
x=3;
System.out.println("inSuperClass:
x="+x);
}
voiddoSomething(){
System.out.println("inSuperClass.doSomething()");
}
}
classSubClassextendsSuperClass{
intx;
SubClass(){
super(); //调用父类的构造方法
x=5; //super()要放在方法中的第一句
System.out.println("inSubClass:
x="+x);
}
voiddoSomething(){
super.doSomething();//调用父类的方法
System.out.println("inSubClass.doSomething()");
System.out.println("super.x="+super.x+"sub.x="+x);
}
}
publicclassInheritance{
publicstaticvoidmain(Stringargs[]){
SubClasssubC=newSubClass();
subC.doSomething();
}
}
运行结果
c:
\>javaInheritance
inSuperClass:
x=3
inSubClass:
x=5
inSuperClass.doSomething()
inSubClass.doSomething()
super.x=3sub.x=5
3.多态性
在java语言中,多态性体现在两个方面:
由方法重载实现的静态多态性(编译时多态)和方法重写实现的动态多态性(运行时多态)。
1)编译时多态
在编译阶段,具体调用哪个被重载的方法,编译器会根据参数的不同来静态确定调用相应的方法。
2)运行时多态
由于子类继承了父类所有的属性(私有的除外),所以子类对象可以作为父类对象使用。
程序中凡是使用父类对象的地方,都可以用子类对象来代替。
一个对象可以通过引用子类的实例来调用子类的方法。
◇重写方法的调用原则:
java运行时系统根据调用该方法的实例,来决定调用哪个方法。
对子类的一个实例,如果子类重写了父类的方法,则运行时系统调用子类的方法;如果子类继承了父类的方法(未重写),则运行时系统调用父类的方法。
在例3-6中,父类对象a引用的是子类的实例,所以,java运行时调用子类B的callme方法。
【例3-6】
importjava.io.*;
classA{
voidcallme(){
System.out.println("InsideA'scallme()method");
}
}
classBextendsA{
voidcallme(){
System.out.println("InsideB'scallme()Method");
}
}
publicclassDispatch{
publicstaticvoidmain(Stringargs[]){
Aa=newB();
a.callme();
}
}
运行结果
c:
\>javaDispatch
InsideB'scallme()method
◇方法重写时应遵循的原则:
1)改写后的方法不能比被重写的方法有更严格的访问权限(可以相同)。
2)改写后的方法不能比重写的方法产生更多的例外。
4.其它
◇final关键字
final关键字可以修饰类、类的成员变量和成员方法,但final的作用不同。
1)final修饰成员变量:
final修饰变量,则成为常量,例如
finaltypevariableName;
修饰成员变量时,定义时同时给出初始值,而修饰局部变量时不做要求。
2)final修饰成员方法:
final修饰方法,则该方法不能被子类重写