Java程序设计精讲三 第四章 面向对象程序设计1
1 类和对象
1.1. 类的定义
类的定义也称为类的声明。类中含有两部分元素,分别是数据成员变量和成员方法。
类定义的一般格式:
1 2 3 4 5 6 7 8 9 10 11 12
修饰符class类名 [extends父类名] { 修饰符类型成员变量1; 修饰符类型成员变量2; ... 修饰符类型成员方法1(参数列表){ 方法体 } 修饰符类型成员方法2(参数列表){ 方法体 } ... }
类型 private 无修饰符 protected public 同一类 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark: 同一包中的子类 :x: :white_check_mark: :white_check_mark: :white_check_mark: 同一包中的非子类 :x: :white_check_mark: :white_check_mark: :white_check_mark: 不同包中的子类 :x: :x: :white_check_mark: :white_check_mark: 不同包中的非子类 :x: :x: :x: :white_check_mark:
1.2. 构造方法
1.2.1. 构造方法概述
构造方法的名字与类名相同,没有返回值,在创建对象实例时通过new运算符自动调用。同时为了便于创建实例,一个类可以有多个具有不同参数列表的构造方法,即构造方法可以重载。
1
2
3
// 在类Xyz中定义了两个构造方法︰
Xyz Xyzl = new Xyz( ); //使用第1个构造方法
xyz Xyz2 = new Xyz(5); //使用第2个构造方法
构造方法的作用是用来创建类的实例,构造方法不能从父类继承。另外,构造方法没有返回值类型。一般来讲,构造方法应该为所有的成员变量赋初值,成员变量的值亦称为对象的属性值。
1.2.2. 默认构造方法
每个类都必须至少有一个构造方法。如果程序员没有为类定义构造方法,系统就会自动为该类生成一个默认的构造方法。
默认构造方法的参数列表及方法体均为空,所生成的对象的各属性值也为零或空。
1.2.3. 构造方法重载
在进行对象实例化时可能会遇到许多不同情况,于是要求针对所给定的不同的参数,调用不同的构造方法。这时,可以通过在一个类中同时定义若干个构造方法,亦即对构造方法进行重载来实现。 为了能够简化代码的书写,可以在其中一个构造方法中引用另一个构造方法。可以使用关键字 this 来指代本类中的其他构造方法。
1.2.4. this引用
this除了可以用在构造方法中之外,还可以用来指明要操作的对象自身。在类定义的方法中,Java自动用this关键字把所有变量和方法引用结合在一起。因此,程序中可以不写这个关键字。
1.3. 对象的创建和初始化
1.3.1. 创建对象实例的格式:
变量名=new 类名(参数列表);
也可以与变量声明合在一起使用:类名 变量名=new 类名(参数列表);
当通过new为一个对象分配内存时,如果构造方法中没有为成员变量提供初值,则Java进行自动初始化。对于数值变量,赋初值0;对于布尔变量,赋初值false ;对于引用,即对象类型的任何变量,使用一个特殊的值null作为初值。 定义类时,可以对成员变量进行显式的初始化,即在声明这些变量的同时,直接给出它们的初值。
1
2
3
4
5
6
7
8
public class Initialized{
private int x = 5; //显式的初始化
private String name ="Fred";//显式的初始化
private Date created = new Date ();
private Date edited; // 未初始值 -null
...
}
1.3.2. 使用对象中的数据和方法
格式如下︰
1
2
对象引用.成员数据;
对象引用.成员方法(参数列表);
因为引用的特殊性,故给引用赋值时,它的含义与基本类型变量的赋值不一样。
2 定义方法
2.1. 方法的定义
方法定义的一般格式∶ 修饰符 返回类型方法名(参数列表)块
说明:
- 方法名必须是一个合法的标识符。
- 返回类型是方法返回值的类型。如果方法不返回任何值,则应该声明为void。Java对侍返回值的要求很严格,方法返回值必须与所声明的类型相匹配。如果方法声明有返回值,比如说是int,那么方法从任何一个分支返回时都必须返回一个整数值。
- 修饰符段可以含有几个不同的修饰符,其中限定访问权限的修饰符包括public、protected和private。
- 参数列表是传送给方法的参数表。表中各元素间以逗号分隔,每个元素由一个类型和一个标识符表示的参数组成。
- 块表示方法体,是要实际执行的代码段,是由一对大括号括起来的语句序列。方法体中一般使用return语句表示方法的结束。如果方法的返回类型不是void,则需要在return语句中指明方法的返回值。
2.2. 按值传送
2.2.1. 概念
传给方法的值称为实参。 方法的参数列表中列出的值称为形参。
2.2.2. Java“按值”传送实参
基础数据类型不变,引用数据类型改变
- 如果形参是基本数据类型的,则调用方法时,将实参的“值”复制给形参。返回时,形参的值并不会带回给实参,即在方法内对形参的任何修改,都不会影响实参的值。
- 如果形参是引用,则调用方法时传递给形参的是二个地址,即实参指向的对象的首地址方法返回时,这个地址也不会被改变,但地址内保存的内容是可以改变的。因此,当从方法中退出时,所修改的对象内容可以保留下来
2.3. 重载方法名
2.3.1. 概念
允许多个方法使用同一个方法名,这就是方法名的重载( Overload )。
2.3.2. 方法签名
方法名称加上方法的参数列表(包括方法中参数的个数、顺序和类型)称为 方法签名。方法重载时,方法签名一定不能相同。Java规定,方法的参数列表必须不完全相同。2.3.3. 重载方法有两条规则
- 调用语句的实参列表必须足够判断要调用的是哪个方法。实参的类型可能要进行正常的扩展提升(如浮点数变为双精度数),但在有些情况下会引起混淆。
- 方法的返回类型可以相同也可以不同。两个同名方法仅有返回类型不同,而参数列表完全相同,这是不够的,因为在方法执行前不知道能得到什么类型的返回值,因此也就不能确定要调用哪个方法。重载方法的参数列表必须不同。
3 静态成员
静态成员∶又称类成员,在类的定义中定义的一种特殊的成员,用static修饰,静态成员是不依赖于特定对象的内容。包括静态变量和静态方法。
如果类中包含静态成员,则系统只在类定义时为静态成员分配内存,此时还没有创建对象,也没有对对象进行实例化。以后生成该类的实例对象时,将不再为静态成员分配内存,不同对象的静态变量将共享同一块内存空间。(一般类的每个实例化对象内存空间相互独立)。
3.1. 静态变量
- 静态变量也被称为类变量,将一个变量定义为静态变量的方法就是将这个变量标记上关键字
static
。用来被类的多个实例对象所共享,以实现多个对象之间的通信,或用于记录已被创建的对象的个数等。 - 静态变量从某种意义上来说相当于其他程序设计语言中的全局变量。静态变量是唯一为类中所有对象共享的变量。引用这一变量时甚至无需生成该类的一个对象,而是直接利用类名来指向它。
3.2. 静态方法
或称类方法,如果需要在尚未创建一个对象实例的时候就去引用方法的程序代码,那么标记上关键字static即可实现。静态方法不依赖于特定对象的行为。
调用静态方法时,前缀使用的是类名,而不是对象实例名。如果从当前类中的其他方法中调用,则不需要写类名,可以直接写方法名。
3.2.1. 两个特别的限制必须注意
- 由于静态方法可以在没有定义它所从属的类的对象的情况下加以调用,故不存在this值。因此,一个静态方法只能使用其内部定义的参数或静态变量,如果想使用非静态变量将引起编译错误。
- 静态方法不能被重写
。也就是说,在这个类的后代类中,不能有相同名称、相同参数列表的方法。
4 包装类
4.1. 概念
Java要管理的数据仅有两类,即基本数据类型值及对象引用。但当想用处理对象一样的方式来处理基本类型的数据时,必须将基本类型值“包装”为一个对象。为此,Java提供了包装类。 Integer ageObj = new Integer( 40 ) ;
4.2. 基本数据类型对应的包装类
所有的包装类都定义在java.long包中
注意:和其他的包装类不一样的是,Void类不能被实例化,只表示void引用的概念。
基本数据类型 | 包装类 | 基本数据类型 | 包装类 |
---|---|---|---|
byte | Byte | double | Double |
short | Short | char | Character |
int | Integer | boolean | Boolean |
long | Long | void | Void |
float | Float |
4.3. lnteger类少的几个方法(其他的包装类有类似的方法)
Integer( int value):构造方法,创建Integer对象,用来保存值value。
byte byteValue ( )、double doubleValue ( )、 float floatValue ()、int intValue ( )、 long longValue():按各自对应的基本数据类型返回Integer对象的值。
static int parselnt(String str):按int类型返回存储在指定字符串str中的值
调用静态方法时不依赖于任何的实例对象。以parseInt为例,它将保存在字符串中的值转为对应的int 型值。如果字符串对象str中的值是“987”,则下行代码将字符串转为整型量987,并将它保存在int型变量num 中。
num = Integer. parselnt( str);
static String toBinaryString (int num)、static String toHexString (int num)、static String toOctalString(int num):将指定的整型值在对应的进制下按字符串形式返回。
4.4. 自动装箱、自动拆箱
自动将基本数据类型转换为对应的包装类的过程称为自动装箱(Autoboxing)。
1
2
3
4
5
6
7
8
9
// 下面的代码将int型值69赋给 Integer对象引用obj1 :
Integer objl ;
int num1 =69;objl = numl; //自动创建 Integer对象
// 逆向的转换称为拆箱(Unboxing),需要时也是自动完成的。
Integer obj2 = new Integer(69) ;
int num2;
num2 = obj2;
//自动解析出int型
// —般来说,基本数据类型与对象之间的赋值是不相容的。
自动装箱与自动拆箱仅能用在基本数据类型与对应的包装类之间。其他的情况,如将基本数据类型赋给对象引用变量,或是相反的过程,都会导致编译错误。