Java面向对象程序设计.docx
- 文档编号:27505283
- 上传时间:2023-07-02
- 格式:DOCX
- 页数:18
- 大小:25.27KB
Java面向对象程序设计.docx
《Java面向对象程序设计.docx》由会员分享,可在线阅读,更多相关《Java面向对象程序设计.docx(18页珍藏版)》请在冰豆网上搜索。
Java面向对象程序设计
第三章Java面向对象程序设计
3.1了解面向对象程序设计的基本概念
3.2掌握类的使用方法
3.3熟悉对象的创建与使用方法
3.4了解包的创建与使用方法
3.1了解面向对象程序设计的基本概念
一、对象
现实世界中,对象(Object)就是客观存在的某一事物。
一辆自行车,一台计算机,它们都可以视为对象。
对象普遍具有两个特征:
状态(属性)和行为。
比如,小鸟有名称、体重、颜色等状态和飞行、觅食等行为;同样,自行车也有品牌、外观、重量等状态和刹车、加速、减速等行为。
在面向对象程序设计中,对象是一组数据和相关方法的集合。
程序中可通过变量向其传递或获取数据,而通过调用其中的方法执行某些操作。
在Java中,对象必须基于类来创建。
类是用来描述一组具有共同状态和行为的对象的原型,是对这组对象的概括、归纳与抽象表达。
在面向对象程序设计中,可以让具有共同特征的对象形成类,它定义了同类对象共有的变量和方法。
通过类可以生成具有特定状态和行为的实例,这便是对象。
从某种程度上讲,Java编程就是设计类,在编程中可以采用自定义方法或继承方法设计一个类。
此外,还可在编程时利用类来创建对象,然后改变对象变量值和调用对象方法来实现程序的某些功能。
二、类
三、封装
封装(Encapsulation)是将代码及其处理的数据绑定在一起的一种编程机制,该机制保证了程序和数据都不受外部干扰且不被误用。
理解封装性的一个方法就是把它想成一个黑匣子,它可以阻止在外部定义的代码随意访问内部代码和数据。
对黑匣子内代码和数据的访问通过一个适当定义的接口严格控制。
封装的目的在于使对象的设计者和使用者分开,使用者不必知道对象行为实现的细节,只需要使用设计者提供的接口来访问对象。
封装是OOP设计者追求的理想境界,它可以为开发员带来两个好处:
模块化和数据隐藏。
模块化意味着对象代码的编写和维护可以独立进行,不会影响到其他模块,而且有很好的重用性;数据隐藏则使对象有能力保护自己,它可以自行维护自身的数据和方法。
因此,封装机制提高了程序的安全性和可维护性。
四、继承
继承是面向对象程序设计中两个类之间的一种关系,是一个类可以继承另一个类(即它的父类)的状态和行为。
被继承的类称为超类或父类,继承父类的类称为子类。
一个父类可以同时拥有多个子类,这时这个父类实际上是所有子类的公共变量和方法的集合,每一个子类从父类中继承了这些变量和方法。
然而,子类也可以不受父类提供的状态和行为的限制。
子类除了具有从父类继承而来的变量和方法外,还可以增加自己的变量和方法。
子类也可以改变从父类继承来的方法,即可以覆盖继承的方法。
继承使父类的代码得到重用,在继承父类提供的共同特性的基础上增加新的代码,从而使编程不必一切从头开始,进而有效提高了编程效率。
五、多态
多态性可以用“一个对外接口,多个内在实现方法”来表示。
也就是说,我们可以在一个类中定义多个同名方法,程序在调用某个方法时,系统会自动根据参数类型和个数的不同调用不同的方法,这种机制被称为方法重载。
此外,当我们利用继承由父类创建子类时,如果父类中的某些方法不适合子类,我们无法删除它们,但可以重新定义它们,这被称为覆盖。
如此一来,当我们利用子类创建对象时,如果调用对象的某个方法,系统会首先在子类中查找此方法。
如果找到,则调用子类的方法;否则,将向上查找,即在父类中查找此方法。
这种情况被称为父类与子类之间方法的多态性。
3.2掌握类的使用方法
下面我们结合Java程序的格式来详细介绍类的声明方法:
package包名//声明程序所在包
import包名.*//导入外部包,可包含多条import语句,以导入多个外部包中的类
import包名.类名
//声明和定义类
[类修饰符]class类名[extends父类名称][implements接口名称列表]{
//声明成员变量或常量
[访问控制修饰符][static][final]<数据类型>变量名或常量名。
……//定义其他成员变量或常量
//声明和定义成员方法
[访问控制修饰符][abstract][static][final][native][synchronized]
返回类型方法名(参数列表)[throws异常类型列表]
{
……//方法体
}
……//定义其他方法
}
……//定义其他类
解释说明:
(1)在一个Java文档中可以包含多个类,但最多只能有一个为公
共类(即publicclass,也可以没有)。
(2)如果存在publicclass的话,该类的类名必须与文档名相同。
(3)main方法是Java应用程序的入口,如果文档中存在public
class和main方法,则main方法必须位于publicclass中。
main方法的格式如下:
publicclass类名{
//成员变量列表
publicstaticvoidmain(String[]args){
//局部变量声明
//方法体
}
}
一、类声明
类声明定义了类的名字及其他属性。
类声明的一般格式如下:
[类修饰符]class类名[extends父类名称][implements接口名称列表]{
……
}
其中,class关键字和类名是必需的,[]表示可选项。
类名是要声明的类的名字,它必须是一个合法的Java标识符,习惯上首字母要大写。
1.类修饰符
类修饰符有public、abstract和final。
如果没有声明这些类修饰符,Java编译器默认该类为friendly类,对于这些类,只有同一包中的类可以访问。
public(公共的):
带有public修饰符的类称为公共类,公共类可以被
任何包中的类访问。
不过,要在一个类中使用其他包中的类,必须在
程序中增加import语句。
abstract(抽象的):
带有abstract修饰符的类称为抽象类,相当于类
的抽象。
一个抽象类可以包含抽象方法,而抽象方法是没有方法体的
方法,所以抽象类不具备具体功能,只用于衍生出子类。
因此,抽象
类不能被实例化。
final(最终的):
带有final修饰符的类称为最终类。
不能通过扩展最
终类来创建新类。
也就是说,它不能被继承,或者说它不能派生子类。
2.说明一个类的父类
extends关键字用来告诉编译器创建的类是从父类继承来的子类,父类必须是Java系统的预定义类或用户已经定义好的类。
一个类只能有一个父类,但一个父类可以有多个子类。
3.说明一个类所实现的接口
implements关键字用来告诉编译器类实现的接口,一个类可以实现多个接口,多个接口之间用逗号分隔,其形式为:
implementsinterface1,interface2,…。
使用接口的主要目的是为了使程序的功能描述和功能的具体实现相分离,从而使程序结构更清晰。
4.类体
类体是类功能实现的主体,是Java语句的集合。
类体中一般定义三类要素:
成员变量和常量、构造方法和方法。
其中,成员变量和常量用来刻画对象的状态,方法用来描述对象的行为,而构造方法一般用来初始化成员变量。
1.访问控制修饰符
使用访问控制修饰符可以限制访问成员变量或常量的权限。
访问控制修饰符有4个等级:
private、protected、public以及默认(即不指定修饰符)。
二、成员变量与常量
成员变量或常量声明必须放在类体中,其一般形式为:
[访问控制修饰符][static]<数据类型>变量名。
[访问控制修饰符][static][final]<数据类型>常量名。
类型
private
protected
public
默认
所属类
可访问
可访问
可访问
可访问
同一个包中的其他类
不可访问
可访问
可访问
可访问
同一个包中的子类
不可访问
可访问
可访问
可访问
不同包中的子类
不可访问
可访问
可访问
不可访问
不同包中的非子类
不可访问
不可访问
可访问
不可访问
2.static变量(类变量或静态变量)
Java中包括两种类型的成员变量:
实例成员变量和类成员变量,简称实例变量和类变量。
如果用static关键字修饰成员变量,则该变量是一个类变量(又称静态变量)。
不加static修饰的成员变量称为实例变量。
packageChapter3
classConcentCircle{
publicstaticintx=100,y=100。
//定义圆心坐标变量
publicintr。
//定义半径变量
publicstaticvoidmain(Stringargs[]){
ConcentCirclet1=newConcentCircle()。
//创建对象
ConcentCirclet2=newConcentCircle()。
t1.x+=100。
//设置圆心的横坐标
t1.r=50。
//初始化半径变量
t2.x+=200。
t2.r=150。
System.out.println("Circle1:
x="+t1.x+",y="+t1.y+",r="+t1.r)。
System.out.println("Circle2:
x="+t2.x+",y="+t2.y+",r="+t2.r)。
}
}
三、方法的声明与实现
1.方法定义的一般形式
在Java中,方法在类体中定义。
与类一样,方法的定义也包括两个部分:
方法声明和方法体。
方法声明的一般形式为:
[访问控制修][abstract][static][final][native][synchronized]
返回类型方法名(参数列表)[throws异常类型]{
……//方法体
}
2.方法的修饰符
方法的修饰符分为访问控制修饰符和非访问控制修饰符。
方法的访问控制修饰符与成员变量的访问控制修饰符的用法是一样的。
(1)abstract方法(抽象方法)
带有abstract修饰的方法称为抽象方法,是指没有方法体的方法。
不过,抽象方法只能出现在抽象类中。
(2)static方法(类方法或静态方法)
方法与成员变量类似,也分为实例方法和类方法(又称静态方法)。
带有static修饰符的方法称为类方法,不加static修饰的方法称为实例方法。
实例方法是属于某个对象的方法,即每个对象的实例方法都有自己专用的内存空间。
类方法是属于整个类的,它被该类的所有对象共享。
类方法与实例方法请参考【例5】。
(3)final方法(最终方法)
带有final修饰的方法称为最终方法。
在面向对象程序设计中,子类可以覆盖父类的方法。
但是,如果父类的某个方法被final修饰,则其子类就不能覆盖这个方法,只能继承这个方法。
因此,这样可以防止子类对父类的关键方法进行修改,保证了程序的安全性。
(4)native方法(本地方法)
用其他语言编写的方法在Java程序中称为本地(native)方法。
由于native方法的方法体是使用其他语言在程序外部编写的,所以native方法没有方法体。
(5)synchronized方法(同步方法)
同步方法用于多线程编程。
多线程在运行时,可能会同时存取一个数据。
为了避免数据的不一致性,可以将方法声明为同步方法,进而对数据加锁,以保证线程的安全。
(6)throws异常类型列表
程序在运行时可能会发生异常现象。
每一个异常都对应着一个异常类。
如果希望方法忽略某种异常,可将其抛出,让它的“上级”(如调用它的对象等)来处理,从而使程序得以继续运行。
3.方法的返回类型
一个方法必须声明其返回类型,方法的返回类型可以是Java中的任意数据类型。
当一个方法不需要返回数据时,返回类型必须是void(空)。
如果一个方法具有返回值,则在方法体中使用return语句把一个确定的值返回给调用该方法的语句。
4.方法的参数传递
当编写一个方法时,一般会在方法名之后给出一个参数列表(称为方法的形参)来声明该方法所需要的参数类型和参数。
参数列表由参数类型和参数名称组成,各参数之间用逗号分隔。
在Java中,可传递的参数(称为方法的实参)可以是任何数据类型,包括基本数据类型、数组或对象,它必须与方法的形参完全对应。
其中,传递基本类型的参数时,编译器会将参数的值传递到方法中。
在方法中修改传递过来的参数的值,并不会影响原参数的值。
请参考【例6】与【例7】。
5.重载方法
Java支持重载方法,即多个方法可以共享一个名字。
但是,各方法之间必须在参数个数、顺序或类型方面有所区别。
publicstaticStringdoubleIt(Stringdata){//参数类型为String
System.out.println(data+data)。
returndata+data。
}
publicstaticintdoubleIt(intdata){//参数类型为int
System.out.println(2*data)。
return2*data。
}
6.方法体中局部变量的特点
在方法体中声明的变量称为局部变量,它只能在方法体内使用。
另外,我们也可以利用“{……}”方式来声明代码块,从而限制局部变量的作用域(即变量可被使用的代码块范围)。
因此,局部变量的作用域开始于它的声明处,结束于当前代码块结束处。
如果没有声明代码块,则其开始于声明处,结束于方法体结束处。
voidfunc(){
intz。
//局部变量z作用域开始于它的声明处
{//程序代码块,声明变量作用域仅限于当前代码块
intx=75。
}//x的作用域到此结束
inty=23。
//局部变量y的作用域开始于此处
z=x+y。
//非法,因为当前位置x变量已经消亡
}//局部变量y和z的作用域到此结束。
7.在方法体中使用this关键字
this用来表示当前类,它主要有以下几种用法:
当成员变量的名字和局部变量的名字相同时,如果要在方法中访问
成员变量,可以使用this关键字。
在方法体中,通过this关键字可访问当前类的成员变量和方法。
辅助调用类的构造方法,尤其是当构造方法有多个时。
classPoint3DextendsPoint2D{
protectedintx,y,z。
publicPoint3D(intx,inty){//第一个构造方法
//调用类的另一个构造方法,调用该构造方法时,传来的实参x//和y被赋予成员变量x和y,而成员变量z被赋予了0
this(x,y,0)。
}
publicPoint3D(intx,inty,intz){//第二个构造方法
this.x=x。
this.y=y。
this.z=z。
}
}
四、类的构造方法
为了便于在基于类创建对象时向对象传递参数,以及对类的成员变量进行初始化。
我们经常会为类编写一个或多个特殊的方法——构造方法。
类的构造方法有如下几个特点:
(1)每个类都有一个默认的构造方法,它既无参数又无返回值,其作用是使用new操作符创建新对象后初始化新建对象。
(2)一旦为类编写了构造方法,默认的构造方法将被覆盖。
(3)构造方法仅在使用new操作符创建新对象时执行一次,而且一般不能用“对象名.方法名”形式来显式调用。
(4)编写构造方法的目的通常是为了向对象传递参数,以及对类的成员变量进行初始化。
(5)构造方法同样支持方法重载。
(6)构造方法的名称必须与类名完全相同,并且不返回任何值。
(7)构造方法不能被static、final、abstract、synchronized和native等修饰符修饰,并且带参数的构造方法不能被子类继承。
实例3-1计算斐波纳契数列
【实例描述】
意大利著名数学家斐波纳契曾经提出了“著名的兔子问题”:
有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子不死,问每个月的兔子总数为多少?
答案是一组非常特殊的数字,即1、1、2、3、5、8、13、21…以上这些数字就是著名的“斐波纳契数列”。
packageChapter3。
publicclassFibonacci{
publicstaticlongfib_1(intn){//定义实现递归算法的方法
longf1,f2。
if(n==0||n==1){//如果n=0或n=1返回n
returnn。
}else{
f1=fib_1(n-1)。
f2=fib_1(n-2)。
return(f1+f2)。
//否则返回fib(n-1)+fib(n-2)
}
}
publicstaticlongfib_2(intn){//定义实现循环算法的方法
longf1=0,f2=1。
longsum=0。
if(n==0||n==1){
returnn。
}
for(inti=1。
i i++){ sum=f1+f2。 f1=f2。 f2=sum。 } returnsum。 } publicstaticvoidmain(String[]args){ System.out.println("递归实现: ")。 for(inti=1。 i<11。 i++){ System.out.print(fib_1(i)+",")。 } System.out.println("\n循环实现: ")。 for(inti=1。 i<11。 i++){ System.out.print(fib_2(i)+",")。 } } } 3.3熟悉对象的创建与使用方法 一、对象的创建 创建一个对象包括声明对象引用变量(即声明对象)和为对象分配内存空间(即创建对象)两个步骤。 类是创建对象的模板,即利用一个已存在的类可以创建多个对象,被创建的对象称为类的实例对象,简称类的实例(或对象)。 我们把创建实例对象的过程称为类的实例化。 1.声明对象引用变量 声明对象引用变量即为对象指定所属类及命名该对象引用变量名称。 对象引用变量简称对象变量。 声明对象的一般格式为: 类名对象名; 2.为声明的对象分配内存 在Java中,使用new运算符和类的构造方法为声明的对象分配内存。 new称为操作符或运算符,它的任务是实例化对象,同时负责调用类的构造方法完成新对象的初始化任务。 创建对象的语法格式如下: <对象名>=new<构造方法名>([参数列表])。 其中,参数列表是可选的,它取决于构造方法自身的情况。 提示: 对象声明和分配内存两个步骤也可以用一个等价的步骤完成,例如: PaintRectangleb2=newPaintRectangle(170,40,60,60)。 二、对象的使用 创建对象后,一般可通过如下格式来访问对象的变量和调用对象的方法: <对象名>.<变量名> <对象名>.<方法名> 三、Java的垃圾回收机制——对象的清除 Java平台允许创建任意个对象(当然会受到系统资源的限制),Java虚拟机会自动判断创建的对象是否还被引用,如果不再被引用,它会自动释放其占用的内存空间。 这种定期检测不再使用的对象并自动释放内存空间的过程称为垃圾回收机制。 Java有一个垃圾回收器,它周期性扫描对象的内存区,并将没有被引用的对象作为垃圾收集起来,定期地释放不再被使用的内存空间。 1.垃圾回收器 2.撤销方法finalize 在一个对象被垃圾回收器收集之前,垃圾回收器将给对象一个机会来调用自己的finalize()方法,将对象从内存中清除。 实例3-2计算一元二次方程的根 【实例描述】 编写一个一元二次方程的求解程序,实现功能: 当判别式大于等于0时,输出两个实数根;当判别式小于0时,输出两个虚数根。 packageChapter3。 publicclassYYECFC{ doublex1,x2。 privatedoublea,b,c。 publicYYECFC(doublea,doubleb,doublec){//带参数构造方法初始化成员变量 this.a=a。 this.b=b。 this.c=c。 } voidreal_root(doubledelt){//计算方程实根的方法 x1=(-b+Math.sqrt(delt))/(2*a)。 x2=(-b-Math.sqrt(delt))/(2*a)。 System.out.println("delt>=0,方程的实根为\nx1="+x1)。 //输出方程的实根 System.out.println("x2="+x2)。 } voidimag_root(doubledelt){//计算方程虚根的方法 doublereal,imag。 real=(-b)/(2*a)。 imag=Math.sqrt(-delt)/(2*a)。 System.out.println("delt<0,方程的虚根为\nx1="+real+"+"+imag+"i")。 System.out.println("x2="+real+"-"+imag+"i")。 } voidshowRoot(){//根据判别式delt的值,选择调用的方法 doubledelt=b*b-4*a*c。 if(delt>=0)real_root(delt)。 elseimag_root(delt)。 } publicstaticvoidmain(String[]args){ YYECFCy1,y2。 //声明对象 y1=newYYECFC(1,5,10)。 //使用带参数的构造方法创建对象 y1.showRoot()。 //调用对象方法 y2=newYYECFC(1,10,9)。 y2.showRoot()。 } } 3.4了解包的创建与使用方法 一、包的创建、声明与使用 包(package)的组织方式同操作系统中文件夹的组织方式类似,是Java语言中有效管理类的一个机制。 包实际上就是一个存放.class的文件夹,因此,创建包就是创建文件夹。 在要放入包的程序中加入package语句,并且该语句一定要作为程序的第一条
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 面向 对象 程序设计
![提示](https://static.bdocx.com/images/bang_tan.gif)