一、面向对象的基本概念

什么是对象

对象是对现实的抽象与模拟。现实中的每个事物都是一个对象,现实中的抽象事物也可以是对象。

面向对象编程用对象表示事物,用对象间的关系表示事物间的联系,这就是面向对象的基本思想。

事物通常具有属性和行为,体现在对象上就是对象有变量和方法。

变量表示对象的属性,方法表示对象的行为,对象是属性和行为的封装。

面向过程的编程(如C语言)是将问题分解为一个个步骤来解决,而面向对象的编程则是把问题分解为一个个对象来解决。

什么是类

一个类是一组具有相同属性和行为的对象的原型,或者说是对象的模板。

类用来创建对象,当使用一个类创建了一个对象时,也可以说创建了这个类的一个实例。

面向对象的基本特征

1. 封装

把对象的属性和行为封装在一起,形成一个不可分割的实体,只保留有限的对外接口。

在编程上的体现:

  • 将属性及方法定义在一个类中;
  • 对来自类外部的访问进行控制。

2. 继承

继承是描述事物间的一般与特殊关系。

特殊类从一般类继承属性与行为。

例如,轮船和客轮之间是一般和特殊关系,动物和狗之间也是一般和特殊关系。

称一般类为父类(或超类,superclass),特殊类为子类(或派生类,subclass)。

子类继承父类的属性和行为,同时具有自己独特的属性与行为。

比如,客轮除了具有轮船的一般特性之外,还有自己独有的特性。

3. 多态

有两种多态,一种是一个类中有多个操作具有相同的名字,但这些操作所接收的输入参数各不相同,称为方法重载。

另一种多态与继承有关,指父类的方法被不同的子类继承后表现出不同的行为。

例如,“几何图形”是父类,有“绘图”方法,“椭圆”和“多边形”是子类,都继承了 “绘图”这个方法,但表现出的绘图行为各不相同。 

二、类的定义

类定义的语法格式

类是Java程序的基本单位,定义格式如下所示:

1
2
3
[修饰符] class 类名 {                                               
类体
}

class是定义类的关键字,后面跟着类名,一对花括加上括起来的内容称作类体。括号内的修饰符是可选项,目前你们只见过public修饰符,其它的修饰符后面会陆续讲到。

public是修饰符,Person是类名。类名必须是合法的标识符,最好见名知意。习惯上类名的首字母大写,其余字母小写。如果类名由几个单词构成,则习惯上每个单词的首字母大写,其余字母小写。

类体的构成

类体包括:

  • 成员变量:定义在类体中的变量;
  • 成员方法:定义在类体中的函数。成员变量表示对象的属性,成员方法表示对象的行为。

成员变量和成员方法的名字必须是合法的标识符,习惯上字母都小写。若由多个单词组成则从第2个单词开始的首字母大写,其余字母小写。

说明

(1) 成员变量

  • 成员变量的类型可以是Java中的任何一种类型,包括八种基本类型和三种引用类型(类、数组、接口)。
  • 成员变量在整个类体内部都有效,与它在类体中的定义位置无关。
  • 可以在定义成员变量的同时赋初值。
  • 如果定义时没有赋初值,则系统会默认的赋初值(基本类型的初值是0或0.0、false,引用类型是null)。
  • 对成员变量的操作只能在方法体中,不能在类体中。

(2) 成员方法

除构造方法以外的其它方法称为成员方法,成员方法的声明格式如下:

1
2
3
[修饰符] 返回值类型 方法名([参数列表]) {
方法体
}
  • 一对花括号括起来的内容称作方法体。除了抽象方法之外,其它所有方法必须有方法体。如果方法的返回值类型是void类型,则方法体中可以没有任何语句。
  • 方法体包括变量声明和Java语句。
  • 在方法体内定义的变量和方法的形参都是局部变量。
  • 形参在方法体内有效,定义在方法体中的或者代码块(花括号括起来的代码)中的局部变量的作用域是从定义位置开始直到方法结束或代码块结束。
  • 局部变量的名字习惯上小写,若由多个单词组成则从第2个单词开始的首字母大写,其余字母小写。
  • 当方法被调用时局部变量才会被创建,方法执行完毕局部变量就被撤销。
  • 局部变量在使用前必须赋一次初值,否则是语法错误,可以在定义时初始化,也可以定义时不初始化而在使用前赋一次初值。

(3) 构造方法

类有一种特殊的方法称作构造方法,构造方法的名字与它所属类的名字相同,没有返回值类型。

  • 在创建一个类的对象时,系统会自动的调用该类的构造方法。
  • Java允许一个类有多个构造方法,但这些构造方法的参数列表必须不同。

EG

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Rect{

double sideA, sideB;

// 无参数的构造方法
Rect() {
sideA = 5;
sideB = 10;
}

// 有参数的构造方法。
Rect(double a, double b) {
sideA = a;
sideB = b;
}

double computerGirth() {
return (sideA + sideB) * 2;
}
}

三、对象的创建与使用

对象的创建

  • 声明对象变量
    形式: 类名  变量名;
    例:Rect  rectangleOne;

  • 创建对象
    形式:new 类名(构造方法的参数列表);

    例:rectangleOne = new Rect(); 或 rectangleOne = new Rect(10,20);

  • 声明和创建可一步完成:Rect  rectangleOne = new Rect(10,20);

说明

  • 用new运算符创建对象时,系统会自动调用构造方法。
  • 如果创建对象时有初始化操作,可以放在构造方法里执行,在构造方法中可以执行任意合法的Java语句。
  • 如果一个类没有定义构造方法,系统会为这个类添加默认的构造方法(无参数的空方法),否则不会为该类添加默认的构造方法。
  • 当类有多个构造方法时,系统根据创建对象时的参数列表来确定调用哪个方法,哪个参数列表能匹配上就调用哪个。

对象的使用

使用圆点符“.”访问对象的成员变量和成员方法。

  • 访问对象的成员变量: 对象名.变量名;
  • 访问对象的成员方法: 对象名.方法名(实参列表);

对象的引用

对象创建的过程:

  • 在内存中创建对象;
  • 调用构造方法;
  • 返回对象的引用。

new运算符创建对象成功后返回一个指向内存中该对象的引用,而不是对象自身。引用型变量保存的是对象的引用值而非对象自身。一个引用值是一个16进制的整数,代表一个对象,具有唯一性。在程序中,当把对象的引用赋给一个变量后,就可以通过该变量来访问对象。通常简单称对象变量为对象。

对象数组

数组是相同类型的变量按顺序组成的集合,数组的元素不仅可以是基本类型,还可以是引用类型。

1
Integer [] m = new Integer [10];

需要注意的是,上述代码仅定义并创建了有10个元素的数组m,每个元素是一个Integer类型的引用型变量。引用类型的数组如果没有初始化,系统默认的将每个元素的值初始化为空引用null,所以目前数组的每个元素都是null值。在使用数组m之前,应当为每个数组元素创建一个对象,EG:

1
2
3
for(int n = 0; n < 10; n ++) { 
m[n] = new Integer(n + 1);
}

垃圾回收

对于Java程序,编程者只需要创建对象,而不需要考虑销毁对象,销毁对象由JVM的垃圾回收机制自动完成。当Java程序不再使用某个对象时,JVM的垃圾回收机制会释放该对象所占用的内存。例如,使用赋值语句t1 = t2把t2的引用赋给t1,那么t1就不再引用原来的对象,如果没有其它变量引用该对象,则JVM认为t1原来引用的对象没用了,会销毁该对象。        
如果将关键字null赋给对象变量,如t1 = null,则t1不再引用任何对象。

课后练习题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class List{
public static void main(String [] args){
String a[][] = new String [9][];
for(int i = 0 ; i < 9 ; i++){
a[i] = new String[i + 1];
for(int j = 0 ; j <= i ; j++){
String str = (i+1) + "*" + (j+1) + "=" + (i+1)*(j+1);
a[i][j] = str;
}
}
// foreach输出循环
for(String n[]:a){
for(String m:n){
System.out.print(m + " ");
}
System.out.println("");
}

}
}