一、面向对象的特点
(一)面向对象概论
-
程序中所有事物都是对象。可以将对象想象成一种新类型的变量,它保存着数据,对外提供服务,对自己的数据进行操作。
-
程序是一系列对象的组合。对象之间通过消息传递机制组合起来,相互调用彼此的方法,实现程序的复杂功能。
-
每个对象都有自己的存储空间,可以容纳其他对象。利用封装机制,可以以现有对象为基础构造出新的对象。因此,虽然对象的概念很简单,但程序中可以实现任意复杂度的对象。
-
每个对象都有一种类型。每个对象都是某个类的一个实例,其中类(class)是类型(type)的同义词。类最主要的特征是对外接口。
-
同一类型的所有对象都能够接收相同的消息。子类与父类具有“同一类型”。例如类型 Circle 的对象与类型 Shape 的对象是同类对象,所以 Circle 对象可以接收Shape 对象的消息。这意味着,在程序中可以统一操纵 Shape类体系(包括 Shape及其所有子类),这就是面向对象程序语言中的多态性。
面向对象方法的核心概念——对象、数据抽象、封装、继承和多态。
(二)核心概念解释
1、抽象
对象的含义与结构
对象是面向对象方法中的核心概念,也是理解面向对象技术的关键。人们对于对象并不陌生。在我们的周围存在着许多对象,如电视机、自行车等。现实世界的对象具有两个特征
——状态与行为(字段与方法)。
面向对象程序设计语言中的对象是以现实世界的对象为模型构造的,也具有状态与行为,其中状态保存在一组变量中,而对象的行为通过法实现。因此对象是由变量和相关方法组成的软件体。可以用软件对象(对象)表示现实世界中的对象,也可以表达抽象的概念。
每个对象都有自己专用的内部变量,这些变量的值表示了对象的状态,例如每辆自行车都具有轮子数目、齿轮数目、踏板节奏与当前挡。当对象经过某种操作和行为改变状态时,对应的变量值也要改变。通过检查对象变量的值,就可以了解对象的状态。行为又称为对象的操作。
操作的作用是设置或改变对象的状态。例如自行车具有刹车、加速、减速、换挡等操作,这些操作将改变自行车的踏板节奏与当前挡等变量的值。
2、封装
对象的方法一方面把对象的内部变量包裹、保护起来,使得只有对象自己的方法才能操作这些内部变量;另一方面,对象的方法还是对象与外部环境和其他对象交互、通信的接口,外界对象通过这些接口驱动对象执行指定的行为,提供相应的服务。
特例——类封装的访问权限
3、继承
对象与对象之间的三大关系
-
包含:当对象 A是对象B的一个组成部分时,称对象B包含对象A。例如,每个汽车中都包含一个发动机。在程序中汽车对象与发动机对象之间就是包含关系,或称 has-a,例如a car has a engine。被包含对象将被保存在包含它的对象的内部,例如发动机对象被保存在汽车对象的内部,作为汽车对象的一个组成部分。像这样利用一个已有对象构造另一个对象,在面向对象程序语言中称为合成(composition),是代码重用的一种重要方式。
-
依赖:当对象 A中需要保存对象B的一个引用而不是对象B本身时,称对象A和对象B之间是关联关系此时表示对象B表示对象A的某种属性,但不是对象A的一个组成部分。
例如汽车与汽车制造厂家之间就是一种依赖关系。在汽车对象中有一个引用指向内存汽车对象之外的另一个对象汽车制造厂家。 -
继承:当对象A是对象B的特例时,称对象A继承了对象B。例如山地车是自行车的一种特例,赛车也是自行车的一种特例。则程序中山地车对象与赛车对象都将继承自行车对象。
4、多态
多态的含义
面向对象的多态特征,简而言之就是“对外一个接口,内部多种实现“。
比如是对几何图形实现画画,画园还是画方还是画菱形……
面向对象程序设计语言支持两种形式的多态:运行时多态和编译时多态。编译时多态主要是通过重载(overloading)技术实现的,即在一个类中相同的方法名可用来定义多种不同的方法。运行时多态是在面向对象的继承性的基础上建立的,是运行时动态产生的多态性,是面向对象的重要特性之一,也是比较难以理解的特性。下面主要对运行时多态的概念进行介绍,文中运行时多态将简称为多态。
而当程序运行时,会根据运行时刻基础类对象的具体类型(子类类型)调用该子类对象中相应的接口实现。
(三)UML的六种关系
这一部分详见设计模式专题
UML 类图用于描述系统中所包含的类以及它们之间的相互关系,帮助人们简化对系统的理解,它是系统分析和设计阶段的重要产物
1、继承
2、实现
3、聚合
4、组合
5、关联
6、依赖
五、Java高级特征
包装类与自动装箱与拆箱
引出包装类——
Java 中,从执行效率的角度考虑,基本数据类型如 int,double 等不作为类来对待。同时Java提供了 Wrapper 类即包装类用来把基本数据类型表示成类。每个 Java 基本数据类型在 java. lang 包中都有一个对应的 Wrapper 类。
数值型类型的包装类包括 Byte,Short, Integer, Long, Float 和Double 都是抽象类 java.lang. Number 的子类。
自动装箱和拆箱
自动装箱——当编译器发现程序在应该使用对象的地方使用了基本数据类型的数据,编译器将把该数据包装为该基本类型对应的包装类的对象。
自动拆箱——类似地,当编译器发现在应该使用基本类型数据的地方了包装类的对象,则会把该对象拆箱(有可能出现空指针,当心),从中取出所包含的基本类型数据。
public class AutoBoxingTest{
public static void main(String args[ ]) 1
Integer x, y;
int c;
//自动装箱,将x,Y构造为两个 Integer 对象
x = 22;
y = 15;
if ( (c = x. compareTo (y)) = = 0)
System. out. printin("x is equal to y");
else
if ( c<0 )
System. out. println("x is less than y");
else{
System. out. printin("x is greater than y");
}
System. out. println("The sum of x and y is" + (x+y) );
}}
运行结果如下:
x is greater than y
The sum of x and y is 37
上述代码中——
变量x和y赋予了整型值。但于它们是 Integer 类型的,编译器将自动把它们封装为两个 Integer 对象,这使得下面的x.compareTo(y)方法能正常运行。(有关init与integer的区别请点击这里)
在程序最后的 println()方法中,要进行x和y所包含整型值的加法运算,所以x和y将被自动拆箱,这样它们才能进行整数加法。
六、 异常
6.1异常
在程序运行时打断正常程序流程的任何不正常的情况称为错误或异常。
处理异常
处理是指程序获得异常并处理,然后继续程序的执行。为了使程序安全,Java 要求如果程序中调用的方法有可能产生某种类型的异常,那么调用该方法的程序必须采取相应动作处理异常。异常处理具体有如下,两种方式——
(1)try-catch-finnally语句块。
int x;
try {
x = 1 / 0;
} catch (Exception e) {
System.out.println("这里有个异常");
} finally {
System.out.println("没有异常,或异常被捕获");
}
1、多个catch块
一个或多个 catch块,每个 catch块处理一种可能抛出的特定类型的异常。
在运行时刻,如果 try{}语句块中产生的异常与某个 catch 语句处理的异常类型相匹配,则执行该 catch语句块。
2、一个finally
finally语句定义了一个程序块,可放于 try()或 catch()块之后,该程序块有无异常都会执行,一般用于关闭文件或释放其他系统资源。
3、二者必居其一
try catch finally 语句中,catch 语句可以有一个或多个,finally语句可以省略。但是try语句后至少要有一个catch 语句或finally语句。
(2)将方法中产生的异常抛出。
public class ExceptionTest {
public void testException() throws IOException {
//FileInputStream的构造函数会抛出FileNotFoundException
FileInputStream fileIn = new FileInputStream("E:\\a.txt");
}
}
6.2断言
概念
断言(assertion)是软件开发中一种常用的调试方式,很多语言都支持这种机制,如C,C++等,但是支持的形式不尽相同,有的是通过语言本身,而有的是通过库函数等。Java 中提供了专门的 assert语句,为Java 程序提供了一种错误检查机制。
每个断言都包含了一个 boolean表达式。
如果程序没有错误,则运行 assert 语句时该表达式的值应该为true。如果该表达式的值false,则系统将抛出一个错误。通过验证断言中boolean 表达式为 true,确认了程序行为的正确性,增强了程序员对程序的信心。经验证明,在编程时使用断言是发现程序错误最快和最有效的方法之一。
断言语句的定义
断言语句有两种形式。第一种形式比较简单:
assert expression;
expression 是boolean类型的表达式。
当系统运行该断言语句时将求出该表达式的值,如果是
false 则说明程序处于不正确的状态,系统将抛出一个没有任何详细信息的 AssertionError类型的错误,并且退出。如果 expression的值是true,则程序继续执行。
语句形式
断言语句有两种形式。
第一种形式比较简单:
assert expression;
expression 是boolean类型的表达式。
当系统运行该断言语句时将求出该表达式的值,如果是
false 则说明程序处于不正确的状态,系统将抛出一个没有任何详细信息的 AssertionError类型的错误,并且退出。如果 expression的值是true,则程序继续执行。
断言语句的第二种形式是:
assert expression1: expression2;
当系统运行上述断言语句并且 expression1的值 false,则系统将计算出 expression2的值,然后以这个值为参数调用 AssertionError 类的构造方法,创建一个包含详细描述信息的AssertionError 对象抛出并退出。如果expression1 的值是 true,则expression2将不被计算,程序继续执行。expression2可以是 boolean,char,double,float,int 和 long 基本类型的值或一个 Object 类型的对象,比较常见的是一个描述错误的字符串。
如果在计算表达式时,表达式本身抛出 Exception,那么断言语句将停止运行,而抛出这个 Exception。
举例一:
例如,如果要求输入的参数不能为null,则可以在方法开始加上下列断言语句:
Assert paraneter1 != null : "paramerter is null in test ()":
举例二:
举例三:
检查方法的返回结果是否有效
对于一些计算型方法,可以通过断言语句在方法返回前,检查返回值是否满足必要的性质。例如,对于一个计算绝对值的方法,可以在方法中加人下列断言:
Assert value > = 0 : "Value should be bigger than 0: "+value;
默认关闭
由于断言语句运行时默认是不执行的所以例6-7运行时可使用-ea 选项打开断言检查:
java - ea <calssname>