目录
一. 面向对象程序设计概述
1.1 面向过程的程序设计
如早期出现的编程语言——C语言,当我们要用这种语言来定义一个复杂的数据类型,譬如人力资源系统中涉及的职员(Employee)时,可以用结构体(Struct)来实现,只要结构体中使用那些基本的数据类型来定义职员的工号,姓名,部门,职务,奖金以及薪水等属性就可以了。如果我们要对一个职员进行各种操作,如设置职员的基本情况,薪水和奖金等等,我们必须要为每个操作都定义一个函数,这些函数与职员这个结构体本身的定义没有任何关系,如设置员工号——setEmployeeNo(Struct Employee),设置奖金——setBonus(Struct Employee)等,这些函数都必须接受一个参数,即要操作的对象——职员。程序的重心集中在函数上。
因此面向过程的程序设计最重要的是模块化的思想方法,自上而下逐步求精。程序结构为:
程序 = 数据结构 + 算法
数据是单独的整体,而算法也是单独的整体,也就是说数据和算法是分离的,当程序规模变大时,数据结构相对复杂,对这些数据处理的算法也就变得复杂,有时会超出程序员的控制努力。面向过程程序结构如图所示。
1.2 面向对象的程序设计
在Java语言中,可以将职员(Employee)当作一个主体(对象)来看,定义职员时,除了要指定在面向过程中规定的那些属性外,还要定义好对应这些动作的函数(方法),如设置职员工号——setEmployeeNo(),设置奖金——setBonus(),这些函数都不再接受代表职员的参数。这些函数被调用时,都是针对当前的职员对象。程序的重点集中在主体/对象上。程序结构为:
对象 = (数据结构 + 算法)
程序 = 对象 + 对象 + ...... + 对象
面向对象的程序设计方法是一种以对象为中心的程序设计方法,它包括以下几个主要概念:抽象,对象,类和封装,继承,多态性,消息,结构和关联。本章我们只讲述类和对象。
1.2.1对象
对象是客观世界存在的具体实体,具有明确定义的状态和行为。
对象是封装了数据结构及可以施加在这些数据结构上的操作的封装体。属性和操作是对象的两大要素。属性是对象静态特征的描述,操作是对象动态特征的描述,也称方法或行为。如图描述保时捷汽车对象。
1.2.2 类
类是对象的模板。即类是对一组有相同数据和相同操作的对象的定义,一个类所包含的方法和数据描述一组对象的共同属性和行为。类是在对象之上的抽象,对象则是类的具体化,是类的实例。它包含属性和方法。
如图所示的汽车类图,具体的每一辆车为该汽车类的对象,对象包含了汽车的颜色,品牌,名称等。
二. 类与对象
2.1 类的定义
public class Employee { //定义类:/职员
String employeeName; //类的属性---职员姓名
public void printEmployeeName(){ //类的方法---输出职员的姓名
System.out.println("employee name is " + employeeName);
}
}
其中,定义了一个职员类Employee,该类有一个属性employeeName,一个方法printEmployeeName()。类的属性也叫类成员变量,类的方法也叫类的成员函数。一个类中的方法可以直接访问同类中的任何成员(包括成员变量和成员函数)。
类可以理解成Java一种新的数据类型,它是Java程序设计的基本单位。类的成员变量和成员函数都在类的内部定义。
[访问说明符] [修饰符] class 类名
{
类成员变量声明 //描述对象的状态
类方法声明 //描述对象行为
}
2.2 创建对象
对象是类的实例。定义对象和定义变量一样。Java创建对象的格式如下:
类名 对象名;
例如构建一个职员的实际对象:
Employee employee;
在使用对象之前必须给它们分配内存,这由new关键字来实现,如:
Employee = new Employee();
2.3 成员变量
2.3.1 成员变量的定义
成员变量(类的属性)的声明方式如下:
[访问说明符] [修饰符] 数据类型 变量名;
访问说明符和修饰符任选的,定义由分号终止。
数据类型:被储存数据的类型,可以是Java的有效数据类型。
变量名:定义变量必需的字段,变量名用于定义变量的名称。例如:
class Employee { //定义类:/职员类
String employeeName; //职员姓名
int employeeNo; //职员编号
}
2.3.2 成员变量的使用
(1)在同一个类中使用成员变量。例如:
class Camera{
float price; //价格
String modelName; //产品型号
int numOfPhotos; //照片数目
public void incrementPhotos(){ //增加照片的个数
numOfPhotos++; //使用成员变量numOfPhotos
}
}
(2)从另一个类中使用成员变量。通过创建类的对象,然后使用 “.“ 操作符指向该变量。
class Robot{
Camera camera; //声明Camera对象
public void takePotos(){ //拍照功能的成员函数
camera = new Camera(); //给camera对象分配内存
camera.numOfPhotos++; //增加照片个数
}
}
2.4 成员方法
2.4.1 成员方法的定义
类的方法,也叫类的成员函数,用来规定类属性上的操作,实现类对外界提供的服务,也是类与外界交流的接口。方法的实现包括两部分内容:方法的声明和方法体。
[访问说明符] [修饰符] 返回值类型 方法名(参数列表){
//方法体声明
局部变量声明;
语句序列;
}
2.4.2 成员方法的使用
调用成员函数必须是在方法名后跟括号和分号。
(1)调用同类的成员函数
class Camera{
float price; //价格
String modelName; //产品型号
int numOfPhotos; //照片数目
public void incrementPhotos(){ //增加照片的个数
numOfPhotos++; //使用成员变量numOfPhotos
}
public void clickButton(){
//调用同类的成员函数incrementPhotos();
incrementPhotos()
}
}
(2)调用不同类的成员函数
class Robot{
Camera camera; //声明Camera对象
public void takePotos(){ //拍照功能的成员函数
camera = new Camera(); //给camera对象分配内存
camera.numOfPhotos++; //增加照片个数
camera.clickButton(); //使用camera对象的成员函数clickButton()
}
}
三. 类的构造方法
3.1 构造方法的定义
先来看一段代码:
class Employee{
private double employeeSalary = 3600;
public Employee(){
System.out.println("构造方法被调用!");
}
public void getEmployeeSalary(){
System.out.println("职员的基本薪水是: "+employeeSalary);
}
}
public class TestEmployee{
public static void main(String[] args) {
Employee e = new Employee();
e.getEmployeeSalary();
}
}
通过运行发现,在TestEmployee的main()中并没有调用刚才新加的Employee()方法,但它被自动调用了。这就是”构造方法“。
构造方法的规则如下:
1.构造方法在对象创建时自动调用,它和声明它的类时同名的。
2.构造方法没有返回值类型,因为构造方法不能显示调用。
构造方法语法格式如下:
[访问说明符] 类名(参数列表)
{
//构造方法的语句体
}
参数列表:为参数,可以为空。
构造方法的语句体:构建对象时的语句,也可以为空。
3.2 构造方法的一些细节
(1)在Java的每个类里至少有一个构造方法,如果程序员没有在一个类里定义构造方法,系统会自动为这个类产生一个默认的构造方法,这个默认构造方法没有参数,在其他方法中也没有任何代码,即什么也不做。
(2)声明构造方法时,构造方法一般都是public的,因为它们在对象产生时会被系统自动调用。
四. static修饰符
4.1 static关键字的使用
static是静态修饰符,可以修饰类的属性,也可以修饰类的方法。被static修饰的属性不属于任何一个类的具体对象,是公共的存储单元。任何对象访问它时,取得的都是相同的数值。
4.1.1 静态属性
定义静态数据的简单方法就是在其属性前加上static关键字。例如:
class StaticTest{
static int i = 36;
}
接下来声明两个StaticTest对象,但它们同样拥有StaticTest.i的一个存储空间。这两个对象都共享同样的i。下述代码的运行结果一致:
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
此时,无论st1.i还是st2.i都有同样的值36,因为它们引用的时同样的内存区域。
4.1.2 静态代码块
在类中,也可以将某一块代码声明为静态的,这样的程序块叫静态初始化段。
static
{
语句序列
}
(1)静态代码块只能定义在类里面,它独立于任何方法,不能定义在方法里面;
(2)静态代码块里面的变量都是局部变量,只在本块内有效;
(3)静态代码块会在类被加载时自动执行,而无论加载者是JVM还是其他的类;
(4)一个类中允许定义多个静态代码块,执行的顺序根据定义的顺序进行。
(5)静态代码块只能访问类的静态成员,而不允许访问非静态成员。
4.1.3 静态方法
静态方法声明的一般语法形式如下;
[访问权限修饰符] static [返回值类型] 方法名([参数列表])
{
语句序列
}
使用static时的注意事项:
1、带有静态修饰符的方法只能访问静态属性;
2、非静态方法即能访问静态属性也可以访问非静态属性;
3、非静态方法不能定义静态变量;
4、静态方法中不能使用this关键字;
5、静态方法不能调用非静态方法反之可以。
五. 重载
方法重载(overloading)是在一个类中允许同名方法的存在,是类对自身同名方法的重新定义。重载是一个类多态性的一种表现。
方法重载有不同的表现形式,如基于不同类型参数的重载:
class Add{
public String Sum(String para1,String para2)
public int Sum(int para1,int para2)
}
如相同类型不同参数个数的重载:
class Add{
public int Sum(int para1,int para2)
public int Sum(int para1,int para2,int para3)
}
重载注意事项:
1.在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int, float), 但是不能为fun(int, int));
2.不能通过访问权限、返回类型、抛出的异常进行重新加载;
3.方法的异常类型和数目不会对重新加载造成影响;
4.对于继承来说,如果某一方法在父类中是访问权限是private,那么就不能在子类对其进行重载如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。