第三章Java⾯向对象程序设计
第三章 Java⾯向对象程序设计
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⽂档中可以包含多个类,但最多只能有⼀个为公共类(即public class,也可以没有)。
(2)如果存在public class的话,该类的类名必须与⽂档名相同。
(3)main⽅法是Java应⽤程序的⼊⼝,如果⽂档中存在public class和main⽅法,则main⽅法必须位于public class中。
main⽅法的格式如下:
public class类名{
// 成员变量列表
public static void main(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关键字⽤来告诉编译器类实现的接⼝,⼀个类可以实现多个接⼝,多个接⼝之间⽤逗号分隔,其形式为:
implements interface1,interface2,…;
使⽤接⼝的主要⽬的是为了使程序的功能描述和功能的具体实现相分离,从⽽使程序结构更清晰。
4.类体
类体是类功能实现的主体,是Java语句的集合。类体中⼀般定义三类要素:成员变量和常量、构造⽅法和⽅法。其中,成员变量和常量⽤来刻画对象的状态,⽅法⽤来描述对象的⾏为,⽽构造⽅法⼀般⽤来初始化成员变量。
⼆、成员变量与常量
成员变量或常量声明必须放在类体中,其⼀般形式为:
[访问控制修饰符][static]<;数据类型> 变量名;
[访问控制修饰符][static][final]<;数据类型> 常量名;
1.访问控制修饰符
使⽤访问控制修饰符可以限制访问成员变量或常量的权限。访问控制修饰符有4个等级:private、pro
tected、public以及默认(即不指定修饰符)。
2.static变量(类变量或静态变量)
Java中包括两种类型的成员变量:实例成员变量和类成员变量,简称实例变量和类变量。如果⽤static关键字修饰成员变量,则该变量是⼀个类变量(⼜称静态变量)。不加static修饰的成员变量称为实例变量。
// ConcentCircle.java
package Chapter3;
class ConcentCircle {
public static int x =100, y =100;// 定义圆⼼坐标变量
public int r;// 定义半径变量
public static void main(String args[]){
ConcentCircle t1 =new ConcentCircle();// 创建对象
ConcentCircle t2 =new ConcentCircle();
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⽀持重载⽅法,即多个⽅法可以共享⼀个名字。但是,各⽅法之间必须在参数个数、顺序或类型⽅⾯有所区别。
public static String doubleIt(String data){// 参数类型为String
System.out.println(data+data);
return data+data;
}
public static int doubleIt(int data){// 参数类型为int
System.out.println(2*data);
return2*data;
}
6.⽅法体中局部变量的特点
在⽅法体中声明的变量称为局部变量,它只能在⽅法体内使⽤。另外,我们也可以利⽤“{……}”⽅式来声明代码块,从⽽限制局部变量的作⽤域(即变量可被使⽤的代码块范围)。因此,局部变量的作⽤域开始于它的声明处,结束于当前代码块结束处。如果没有声明代码块,则其开始于声明处,结束于⽅法体结束处。
void func(){
int z;//局部变量z作⽤域开始于它的声明处
java接口有没有构造方法
{//程序代码块,声明变量作⽤域仅限于当前代码块
int x=75;
}//x的作⽤域到此结束
int y=23;//局部变量y的作⽤域开始于此处
z=x+y;//⾮法,因为当前位置x变量已经消亡
}//局部变量y和z的作⽤域到此结束。
7.在⽅法体中使⽤this关键字
this⽤来表⽰当前类,它主要有以下⼏种⽤法:
当成员变量的名字和局部变量的名字相同时,如果要在⽅法中访问
成员变量,可以使⽤this关键字。
在⽅法体中,通过this关键字可访问当前类的成员变量和⽅法。
辅助调⽤类的构造⽅法,尤其是当构造⽅法有多个时。
class Point3D extends Point2D {
protected int x, y, z;
public Point3D(int x,int y){// 第⼀个构造⽅法
// 调⽤类的另⼀个构造⽅法,调⽤该构造⽅法时,传来的实参x //和y被赋予成员变量x和y,⽽成员变量z被赋予了0
this(x, y,0);
}
public Point3D(int x,int y,int z){// 第⼆个构造⽅法
this.x = x;
this.y = y;
this.z = z;
}
}
四、类的构造⽅法
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论