你的位置:首页 > Java教程

[Java教程]Java类和对象


面向对象的程序是由对象组成的,每个对象包含对用户公开的特定功能部分和隐藏的实现部分。在面向对象程序设计(OOP)中,不必关心对象的具体实现。在传统的结构化程序设计中,算法是第一位的,数据结构是第二位的,即首先确定如何操作数,再考虑如何组织数据,以方便操作。而OOP则颠倒了这种次序,将数据放在第一位,然后再考虑操作数据的算法。

一、类

    类是构造对象的模板和蓝图。通俗地说,类相当于建筑的图纸,而对象相当于建筑物。由类构造对象的过程称为创建对象的实例。

Java中通过关键字class定义“类”,后跟类名。例如:

class Person{  // 类的主体内容}

定义了一个Person类。

1.字段和方法

定义一个类时,可以在类里设置两种类型的元素:数据成员和成员函数。其中数据成员是一种对象,可以是任何类型。如果是指向对象的句柄,则必须初始化这个句柄,通过构造器与一个实际对象连接起来。如果是基本数据类型,则可以在类定义的位置直接初始化。

每个对象都为自己的数据成员保有存储空间;数据成员不会在对象之间共享。

class Person{  String name;  double salary;}

通过new关键字创建一个对象。如:

Person p = new Person();

(1)主成员的默认值

某个主数据类型属于一个类成员,那么即是不明确进行初始化,也可以保证他们获得一个默认值。

主类型默认值
Booleanfalse
Char'\u0000'(null)
byte(byte)0
short(short)0
int0
long0L
float0.0f
double0.0d

如果一个变量作为类的成员变量,那么对于主类型一定会得到初始化,要特别注意初始化的值。对于局部变量则会得到一些随机值,如:int x;不会自动初始化为0。

(2)方法

方法的基本组成部分包括名字自变量返回类型以及主体。方法的基本形式为:

返回类型 方法名(/*自变量列表*/) {/* 方法体 */}

返回类型是指调用方法之后返回的数值类型。方法名是对具体方法的标识和引用。自变量列表列出****了想传递给方法的信息类型和名称。

在Java中方法的调用形式为对象名.方法名

1. 用句柄操作对象

    尽管Java是完全面向对象的。但是,操作的标识符实际指向一个对象的“句柄”,又称“引用”。句柄是可以独立存在的,并不是说,拥有一个句柄就必须有一个对象与之对应。比如,int i;定义了一个整型变量i,并不表示它一定有值。如,创建一个String类型的句柄:

String s;

    这里只是创建了句柄,并没有创建对象。由于s并没有与之关联的对象,如果调用s将出现异常。所以,创建时需要进行初始化。

String s = "hello";

    在Java中,通过new关键字创建对象,它将返回对象的引用(即句柄)。所以

String s = new String("hello");

创建了一个内容为"hello"的String对象,并将该对象的句柄(引用)交给了s保存。

2. 数据存储的位置

  1. 寄存器。最快的保存区域,位于处理器内部。寄存器的大小有限,由编译器的分配大小。
  2. 堆栈。驻留在常规RAM(随机访问存储器)区域,通过“堆栈指针”可以改变大小。堆栈指针向下移动,会创建新的内存空间;向上移动,则释放内存空间。创建程序时,Java编译器必须准确地知道堆栈内保存的所有数据的“长度”和“存在的时间”,编译器由此生成相应的代码,以便移动指针。Java对象的句柄保存在其中,但是Java对象并不保存在堆栈中。
  3. 堆。常规用途的内存池,其中保存了Java对象。编译器不知道也不需要知道从“内存堆”或“堆”里分配多少存储空间、数据存留多长时间。
  4. 静态存储。静态指位于固定的位置(在RAM中)。程序运行期间,静态存储的数据将随时供调用。通过static关键字指出一个对象的特定元素是静态的。Java本身本不可能置于静态存储空间。
  5. 常数存储。常数值通常置于程序代码内部,永远不会改变。
  6. 非RAM存储。若数据完全独立于一个程序之外,则程序不运行时仍可存在,并在程序的控制范围之内。例如,流式对象和固定对象。

二、对象

对象的三个主要特性:

  • 对象的行为——可以对对象施加哪些操作,或可以对对象施加哪些方法?
  • 对象的状态——当时加那些方法时,对象如何响应?
  • 对象标识——如何辨别具有相同行为与状态的不同对象?

对象的行为是由可调用的方法定义的。每个对象都保存着描述当前特征的信息,这就是对象的状态。对象的状态不会自发改变。一个设计良好的类,它的对象只能通过调用方法实现,如果不经过方法调用就可以改变对象的状态,说明封装性受到了破坏。

封装:将数据和行为组合在一个包中,并对对象的使用者隐藏了数据的实现方法。封装的关键在于绝对不能让类中的方法直接地访问其他类的实例域。程序仅通过对象的方法域对象数据进行交互。

对象中的数据称为实例域(instance field)或属性。操纵数据的过程称为方法(method)。对于每个特定的对象都有一组特定的实例域值(属性值),这些值的集合就是该对象的当前状态。

类之间的关系

类之间常见的关系:

  • 依赖(“use-a”):一个类的方法操纵另一个类的对象。
  • 聚合(“has-a”):一个类的对象包含另一个类的对象。
  • 继承(“is-a”):用于表示特殊与一般的关系。如果类A扩展类B(A继承B),类A不但包含类B的方法,还有扩展的方法。

一个对象并没有实际包含一个对象,而仅仅引用一个对象。

在Java中,任何对象变量的值都是都是对存储在另外一个地方的一个对象的引用。new操作符的返回值也是一个引用。