类的概述

Java是面向对象语言,面向对象的思想是将客观事物都作为实体,而对象通过实体抽象得到。
类是变量和方法的集合体。类可以嵌套定义。类是Java程序中基本的结构单位。所有的Java 语句出现在方法中,所有的方法都定义在类中。
数组是最简单的复合数据类型,是有序数据的集合。数组的元素可以是值(基本数据类型)、对象或其他数组。一个数组中的所有值都必须是相同的数据类型。
文本字符串是一种参考数据类型,它本身是由java.lang.String定义的对象。类String含有一系列对于字符串操作的方法。

1.类定义

Java 语言编写程序通过新的对象类型机制,就是允许自定义对象类型——类,它是程序的基本要素,由成员变量和成员方法组成。实例化一个类,就能得到一个对象。
类的成员变量可以是基本类型数据、数组或类的实例。
成员方法只在类中定义,用来处理该类数据。类提供外界访问其成员方法的权限,通常,类成员数据都是私有的,而方法是公有的,外界只可能访问成员方法。

类定义由类声明和类体组成。注意类名的第一个字母大写。类必须先定义后使用。

2.类声明

格式:
[修饰符]class类名[extends父类名][implements类实现的接口列表]…

其中用[]括起来的内容为可选项。关键字class是类定义的开始,类名应符合标识符命名规则,第一个字母大写并具有类功能特征。修饰符指明类的访问控制符和类型说明符。关键字ex-
tends指明该类是子类,它的父类名紧跟在后,子类与父类之间有继承关系。关键字implements指明该类实现的接口,后跟接口名列表。修饰符包括:

  • (1)public访问控制符指明该类为公共类,可被其他类访问或引用其成员变量和成员方法。
  • 注意,Java语言规定包含main()方法的主类必须是公共类。
  • (2)默认(也称friendly)即没有访问控制符,表示该类只能被同一个包的类访问和引用,也不能用import语句引入。因为Java语言规定,在一个.java文件中只能有一个public类,这样,文件中其他类就只能都是默认访问控制符。
  • (3)abstract抽象类,指明不能实例化的类。为更贴近人的思维和客观世界。定义它常常为改变它的子类而设置。
  • (4)final最终类,指明该类不能有子类,例如InetAddress类。

3.类体

4.成员变量
成员变量声明格式:
修饰符【public,prolected,private,statie,final,transient,volatile]type变量名;其中type可以是java语言中任意数据类型。而修饰符的含义:

  • (1)public 指明变量为公有。由于面向对象技术的封装要求,应尽量少用公共变量,而是通过公共方法类间接访问类的成员变量,从而提高程序的稳定性。
  • (2)protected指明变量为保护访问。可被同一个包中其他类、不同包中该类的子类以及该类自己访问和引用。保证所有子类都可访问父类,不管这些子类被封装在哪里。
  • (3)private指明变量为私有访问。只能被该类自己访问或调用,是对成员变量的最高级保护。
  • (4)static指明变量为静态变量,否则为实例变量。静态变量不需要类的实例化就可被类直接调用。
  • (5)final指明变量为常量。注意用大写字母。
  • (6)transient 指明变量为暂时性变量,用于实现不同对象存档功能。
  • (7)volatile指明多个线程共享的变量,保证各线程对该变量访问的一致性。

5.成员方法定义和调用
所谓成员方法,是指作为类的成员的方法。方法的定义由方法声明和方法体组成。方法定义的形式如下:
returnType methodName(paramlisl)[throws exceplions]
它表明了在一个方法调用前要知道的一些信息:

  • (1)方法的名称。
  • (2)参数的类型和名称。
  • (3)方法返回值的类型。
  • (4)方法的抛出的异常类型。

方法声明格式:
修饰符【public,protected,private,static,final,abstract,native,synchronized】
returnType methodName([paramlist])[throws exceptions]
{…}
其中修饰符public、protected、private、static、final与成员变量声明意义相同,都是定义方法访问权限。abstract 指明方法是否可以重写,native指明代码是由各种语言集成,synchronized指明多线程可并发共享访问。

提示:Java中的方法的参数传递是传值调用,而不是地址调用。方法不能改变参数值,但可以改变变量值,两个对象之间的参数字段,不能相互交换。

6.方法重载

方法的重载是指多个方法可以享用相同的名字,但参数的数量或类型必须不完全相同,即方法体有所不同,它实现了Java编译时的多态(即静态多态性)性。也就是说,程序可以按参数决定调用对应方法,而此决定是由编译器来做的。

例如,相同名称的构造方法,其参数可以不同:

staff[0]=new Employee(“Harry”,40000);

staff[1]=new Employee(60000);

staff[2]=new Employee();

方法的重载是因为方法在类的继承链中的位置不同,是子类对父类方法进行了重写。

以下例子中,子类Manager 对父类Employee中的getSalary()方法进行了重载,其中返回值增加了经理津贴。下面是方法重载的程序片段:

7.构造方法

构造方法是类中的一种特殊方法,是为对象初始化操作编写的方法,用它来定义对象的初始状态。在Java语言中的每个类都有构造方法,它也是由方法名、参数和方法体组成的。构造方法名必须与类名相同,它没有返回值,用户不能直接调用它,只能通过new自动调用。以下的代码片段中,类BankAccount中的构造方法是BankAccount(double initialBalance)。方法体指明了参数double initialBalance是初始存款余额。构造方法在建立该对象的同时被调用。构造方法在建立该对象的同时被调用。例如,在本例的主方法中,建立BankAccount对象的同时,调用了其构造方法,而且将参数具体定为10000。

构造方法也有成员,访问权限限制。在构造方法中必须使用成员变量,而且当参数与成员变量同名时,就只能用this关键字。以下的代码段中,局部变量y与类的成员变量同名,在方法中如要用成员变量,为区别于局部变量,必须用this关键字。
通常,对程序中可能有二义性的对象,可用this指明当前对象,使程序清晰易读。构造方法也允许重载,使类的实例有多种初值。如果类中没有构造方法,Java语言提供默认的构造方法。
但只要类中提供了构造方法,默认构造方法就无效。
构造方法有下列特点:

  • (1)因为构造方法名与类名必须相同,所以方法首字母小写规则对它不适用。
  • (2)构造方法是给对象赋初值,所以没有返回值,但不用void来声明。
  • (3)构造方法不能被程序调用。
  • (4)构造方法可由编程人员在类中定义,默认时由Java语言自动生成。但它是个空方法,变量被赋予该数据类型的默认值。
  • (5)构造方法可以重载实现不同的初始化方法,调用时按参数决定调用哪个方法。

提示:如程序定义了一个或多个构造方法,在创建对象时,必须用已定义的构造方法来初始化。如Java解释器按参数没有找到相应构造方法,只会报错而不会自动生成空的构造方法。

对象、接口与包

对类实例化,可以生成多个对象,通过这些对象之间的消息传递进行交互,可完成很复杂的功能。一个对象的生命周期分为3个阶段:生成、使用和清除。

1.对象的生成
对象是一组相关变量和相关方法的封装体,是类的一个实例。对象的特征是对象的行为、状态和身份。对象生成包括声明、实例化和初始化三方面内容。一般格式是先定义一个对象变量,再用关键字new生成一个对象,并为对象中的变量赋初始值。
如下所示:
type objectName=new type(【参数】);

其中:type objectName声明是定义对象的类型,它包括类和接口的复合类型。new关键字是实例化一个对象,给对象分配内存,它调用对象的构造方法,返回该对象的引用(存储对象所在堆地址和有关信息,并非内存直接地址)。new可以实例化类的多个不同的对象,分配不同的内存。因此,这些对象之间的状态相互独立。在执行构造方法进行初始化时,构造方法可以重写,按不同类型的参数调用不同的构造方法。例如:

BankAccount account =new BankAccount(10000);
ActionListener adder = new InterestAdder(rale);
Timert=new Timer(1000,adder);

2.对象的使用
对象的使用原则是先定义后使用。对象的使用包括访问类成员变量和方法的调用、对象作为类成员使用和作为方法参数(或返回值)使用。

  • (1)通过“.”运算符实现对成员变量的访问和方法调用。成员变量和方法通过权限设定来防止其他对象的访问。其格式为:
    对象名.调用的方法名或变量名
  • (2)将一个对象声明为类的成员时,要注意在使用前必须对该对象分配内存,也可以用private 修饰符保证数据安全。
  • (3)在方法中使用对象作为参数时,采用引用调用。

从上面程序段看出,用BankAccount account=new BankAccount(10000);生成BankAccount类的对象account后,就可以用account.start(10)来调用方法。而在start()方法中定义对象adder作为Timer()方法的参数,可以用new生成对象的引用,再调用它的方法。

3.对象的清除
对象的清除指释放对象所占用的内存。Java 语言有自动收集垃圾功能,会周期性地回收一些长期不用的对象占用的内存,因此,编写程序时无需对内存的使用操心。但是,自动收集垃圾操作的优先级较低,允许有其他一些办法释放对象所占用的内存。归纳起来对象清除的途径为:

  • (1)依靠Java的垃圾回收机制回收内存。
  • (2)调用System.gc(),请求垃圾回收。
  • (3)Java系统开始运行时,自动调用java.lang.Object.finalize()释放内存。
  • (4)在程序中调用重写的finalize()释放系统资源,其格式为:
    protected void finalize()throws throwable{ super.finalize(); } 通常要用super 来调用基类的finalize()方法.可参见类继承章节。

4.接口
接口是一种只含有抽象方法或常量的一种特殊的抽象类。因此,首先讨论一下抽象类的概念。在Java语言中,用abstract修饰符定义的类称为抽象类,在其中的方法称为抽象方法。ab-stract 类必须被继承,abstract 方法必须被重写,abstract类不能实例化。abstract类的格式为:
abetract class abstractClass(

}

接口是不包含成员变量和方法实现的抽象类,它只包含常量和方法的定义。接口的主要功能是:

  • (1)不管类的层次,可实现互不相关的类具有相同的行为。
  • (2)通过接口说明多个类所需实现的方法。
  • (3)通过接口可以了解对象的交互界面,无需了解对象所对应的类。

接口可以作为一种引用类型来使用。用接口类型变量将实现该接口的类的实例存入,通过这些变量去访问类所实现接口中的方法。这样,与对象所对应的类可以无需了解,而把重点放在交互界面上。
接口不仅是抽象类,其用途胜于抽象类。因为,接口不包括任何实现,所以与存储空间没有任何关系。将多个接口合并,即多重继承就可以很容易实现。

5.包
在Java语言中,每个类生成一个字节文件,该文件名与类名相同。这样,同名类会发生冲突。为解决此矛盾,Java采用包来管理类名空间。包为编程提供了一种命名机制,也是一种可见性限制的机制,还是面向对象方法的封装机制。包将类和接口封装在一起,便于大量类和接口的管理,并有利于类和接口的安全。
定义一个包要用package关键字。

提示:Java语言的java.lang包是编译器自动导人的。因此,编程时使用该包中的类,可省去import导入。但使用其他包中的类,必须用import导入。

##类成员修饰符、继承、内部类、类库

2.继承
继承性是面向对象方法的一个重要基本特征,它使代码可重用,可降低程序复杂性。Java语言中,所有的类都是通过直接或间接地继承 java.lang.Objecter而得到的。对一个类的继承是指在现有类(父类)的基础上构建一个新类(子类),子类重用(继承)了父类的方法和状态,同时还可以向新类中增添新的方法和状态。Java不支持多重继承。通过在类声明中加入extends子句来创建子类,其格式为:

`class SubClass extends SuperClass{...}`


Java中,类是分层次的,当子类的成员变量与父类的成员变量名字相同时,子类的成员变量会隐藏父类的成员变量,当子类的成员方法与父类的成员方法名字、参数列表、返回值类型都相同时,子类的方法是父类的方法的重写(Override)。这样,在子类的对象调用方法时,是按照子类中方法定义执行,隐藏父类的方法的定义。例如:

上面子类SubClass定义的变量和方法都相同,父类的变量被隐藏,方法被重写。这里要强调的是,重写方法必须遵循两个原则:

  • (l)子类方法的访问权限比父类方法的访问权限更高。
  • (2)子类方法不能产生比父类方法更多的异常。

这两个原则是编译器为了实现面向对象方法的多态性,保证程序健壮,避免程序执行时出现访问权限的冲突,并不会漏了异常的捕获。
当子类隐藏了父类的变量,并重写了父类方法后,又要使用父类变量或父类被重写的方法时,可通过super来实现对父类变量的访问和对父类方法的调用。super是用来引用当前对象的父类。super的使用有3种情况:

  • (1)用于访问被隐藏的父类成员变量,其格式为:super.变量名
  • (2)用于调用被重写的父类方法,其格式为:super.方法名;
  • (3)用于调用父类的构造方法,其格式为:super([参数列表]);

在实现子类的构造方法时,按程序初始化过程,必须由高层向低层进行。子类要调用父类的构造方法时,就用super去调用。

面向对象的另一个重要特性是多态性,它是由对象类的继承和封装性结合而引出的。
在Java语言中,体现多态性有两个方面:静态和动态。

静态的多态性是指编译时调用重写方法的一种机制,即同一个方法用不同参数体现程序不同的调用,这是编译器在编译时自动确定实现的。由此可说,方法重载体现了静态的多态性。

动态的多态性是指运行时,利用子类继承父类的所有变量和方法功能,凡是程序使用父类的对象都可用子类的对象来代替。运行时,Java解释器会按照调用方法的对象类型,确定调用子类或父类的方法去执行,这就体现了动态多态性。

实际上,编程时类库可调用新定义子类的方法而不用重新编译,并提供简单的抽象接口,利用继承添加子类和重写方法,这是动态多态性体现的范例。对父类的方法,用多次new可生成多个不同的实例,很容易用多个子类分别调用不同的父类方法。

3.内部类
在一个类的内部嵌套定义的类称为内部类(lnner Class)。与普通的类一样,内部类也具有自己的成员变量和成员方法。同样可以通过建立内部类的对象,去访问其成员变量和调用其成员方法。但还有它不同的地方,其特点有:

(1)内部类的类名只能在定义它的类或程序段中或在表达式内部匿名使用,外部使用它时必须给出类的全名。而且,内部类的类名不允许与包含它的类名相同。
(2)内部类可以使用它所在类的静态成员变量和实例成员变量,也可使用它所在类的方法中的局部变量。
(3)内部类可用abstract 修饰定义为抽象类,也可用private 或protected定义。
(4)内部类可作为其他类的成员,而且可访问它所在类的成员。
(5)除static内部类外,不能在类内声明static 成员。一旦内部类声明为static,就变成顶层类,不能再使用局部变量。这时可声明static成员。
通常,使用内部类来生成事件适配器。在实现图形界面中对鼠标单击、窗口事件、点击菜单等,需要一个类同时继承多个事件适配器类,需要同时实现多个监听器接口,若靠单一的继承机制是很麻烦的事。使用内部类,可以定义多个内部类去分别继承不同事件适配器类,使事件处理很方便。下面是内部类实现接口的抽象片段:

4.类库
Java中,已为编程准备好许多经测试过的类,编程者利用这些类作为基础,将大大简化编程工作。因此,学习Java语言,要对类库尽可能地去熟悉它的内容。类库以包的形式组织,是包的集合。早在J2SE的1.3.1版,类库已有76个包,目前已发展到J2SE1.4.2版,类库的包已过百。
这里简单介绍J2SE1.4类库。J2SE标准平台由工具软件和Java类库(APls)组成。其中,Java编程所必需的默认引用包为lang包,实用工具在util包中,用户界面工具在Swing包和AWT包中。
随着对于Java技术的深入学习,将逐步介绍其他包。J2SE1.4中工具软件+应用程序编程接口APIs构成如表5-2所示。

首先,来看看最基本的java.lang包。该包中所有类都在运行时,由java解释器自动引入,程序不用import语句都可使用其中任何一个类。该包有接口、类、异常等组成。它是Java语言的最底层的类。它包括的最主要的类有:

(1)Object类是Java所有类的根类,其他类都由它扩展而来。因此,在Object类中定义的方法,其他类都可调用。它定义的方法包括:

(2)Class类是用于类操作的类,Class对象由Java编译器自动生成,隐藏在.class文件中,它在运行时为用户提供信息。另外,还提供运行时动态装入环境的操作类ClasLoader。这两类常用方法包括:

(3)System类是一个final类,即不能被实例化的类,它主要提供标准输入、输出和系统环境信息。这在每个程序中都已看到。它有3个很有用的成员变量:in、out和er,分别表示标准输入流对象、标准输出流对象和出错流对象。主要方法有:

(4)Thread类是提供线程操作和管理的类。

一维数组:

数组是一种复合数据类型,在lava中,数组是作为对象来处理的。数组是有限元素的有序集合,数组中的元素具有相同的数据类型,并可用统一的数组名和下标来惟一确定其元素,元素是数组中不可分的最小单位。