一、面向对象的编程概念
观察现实对象两个性质:状态、行为。
面向对象的好处:模块化、隐藏信息。
继承:子类从父类(超类)继承状态和行为;子类可以改变父类的状态和行为。
接口:是无关对象用来进行彼此交互的设备;一个对象可以实现多个接口。
二、语言基础
变量
对象将它的状态存储在变量中;变量是一个由标识符命名的数据项。
声明变量的形式:<类型> <名称>
JAVA语言两大数据类型
原始类型数据(基本数据类型)、引用类型。
原始类型数据是不能再分解的数据类型(8种:byte、short、int、long、float、double、char、boolean),数据在作为函数参数是以“传值”方式工作的;
整数 byte:1字节长的整数;8位有符号的二进制补码整数
short:短整数;16位有符号的二进制补码整数
int:整数;32位有符号的二进制补码整数
long:长整数;64位有符号的二进制补码整数
实数 flat:单精度浮点数;32位IEEE 754浮点数
double:双精度浮点数;64位IEEE 754浮点数
其他类型 char:单一Unicode字符;16位Unicode字符
boolean:布尔值(true或false);8位/1位(8位空间,1位数据)
引用类型包括类(class)、接口(interface)、数组(array)。引用类型有时也称复合类型,它是可以分解为基本类型的数据类型,其数据在作为函数参数时是以“传址”的方式工作的。与原始类型相对,引用类型变量的值是对由此变量代表的一个值或一组值的引用(也就是地址)。
如:
原始类型 int a = 3; //“a”表示变量名称,“3”表示变量值;如果写成“final int a = 3;”,“final”表示不可改变值,所以这里的3(变量值)不可变
引用类型 Staing b = "Hello Java"; //“b”表示引用名称,“Hello Java”表示字浮串数组
流程控制语句
循环 while、do - while、for
判断 if - else、switch - case
异常处理 try – catch – finally、throw
分支 break、continue、label :、return
循环:
while和do – while语句:While语句用于在条件保持为true时反复执行一个代码块;
do – while语句的代码块中的语句至少被执行一次。
for语句:
for语句提供一种迭代某个范围内的值的紧湊方式。
判断:
if – else 语句:if语句使程序能够根据某些条件有选择地执行其他语句;
switch语句用于根据一个整数表达式有条件的执行语句;
注意:必须要有明确的break语句,否则,流程控制将一个接一个的经过后面的case语句
比较if语句和switch语句(if语句可以用于根据某范围的值或条件进行判断;switch语句只用于根据单个整数值进行判断)。
异常处理语句:
当程序发生错误时,程序会抛出一个异常,程序的正常流程被中断;
分支语句:break、continue语句可以和标签语句一起使用,也可以没有标签;
标签是放在一个语句前的标识符,标识符后跟一个冒号;
continue 语句:continue语句用于跳过for、while、do – while循环的当前迭代;
return 语句:返回一个值;不返回值。
三、对象基础和简单数据结构
创建对象:声明一个变量来引用变量;对对象进行实例化(构造器);
用new操作符和构造器从类创建对象。
两种方式使用一个对象:引用一个对象的变量;调用对象的方法。
字符和字符串
JAVA平台包含三个用于处理字符数据的类:
Character:包含单个字符值;定义了一些可用于操作和检查单字符数据的方法(Character类的对象实例包含单个字符值,可用Character对象替代基本类型char)。
String:这个类用于处理由多个字符组成的不可改变的数据。
StringBuffer:存储和操作由多个字符组成的可改变的数据。
字符串和字符串缓冲区
String:不能改变自身的值。
StringBuffer:用于将被修改的字符串。
得到字符串或字符串缓冲区的长度
length方法:返回字符串或字符串缓冲区中包含的字符数。
capacity方法:StringBuffer特有;返回分配给字符串缓冲区的空间量,而不是被使用的空间量。
String类没有capacity方法,因为字符串不能改变。
通过索引从字符串或字符串缓冲区得到字符
charAt(int)方法:得到字符串或字符串缓冲区某索引位置上的字符。
注意:第一个字符串的索引为0;最后一个字符的索引为length – 1;
subString(int), subString(int,int):从字符串或字符串缓冲区中得到多个字符。
在字符串中搜索字符或子字符串
String类提供了两个访问器方法:indexOf 方法从字符串的开头向前搜索;lastIndexOf 方法从字符串的末尾向后搜索;
StringBuffer类不支持indexOf和lastIndexOf方法。
操作字符串
String类有几个方法看起来可以修改字符串。当然,字符串是不能被修改的,所以,这些方法实际上是创建并返回包含结果的另一个字符串。
修改字符串缓冲
字符串缓冲是可以修改的,StingBuffer提供了几个用于修改字符串缓冲区的数据的方法;
如果修改字符串缓冲区的操作造成字符串缓冲区的大小超出它的当前容量,那么字符串缓冲区会自动分配更多的内存。
字符串和编译器
编译器在很多地方自动的使用String和StringBuffer类来处理字符串直接值和字符串连接;
编译器为它遇到的每个字符串直接值自动创建一个新的String对象;
可以使用+操作符连接字符串。
四、类和继承
实现继承:extends关键字
为类提供构造器
构造器用于初始化类的新对象:构造器不是方法,没有返回类型;构造器的声明中可以使用以下访问说明符:
– private
– protected
– public
– 无说明符
将信息传递给方法或构造器
参数类型;
参数名称;
按值传递:参数是原始类型,方法不能改变其值;参数是引用类型,方法不能改变其引用,但可以改变引用对象的值。
从方法返回值
在方法声明中声明方法的返回类型;eturn语句返回值的数据类型必须匹配方法声明的返回类型;方法可以返回原始类型,也可以返回引用类型。
使用this关键字
在实例方法或构造器中,this引用当前对象,也就是被调用的方法或构造器所属的对象;在构造器中,还可以使用this关键字调用相同类中的另一个构造器。
控制对类成员的访问
访问说明符决定其他类是否可以使用某个成员或调用某个方法。Java编程语言支持四种用于成员变量和方法的访问级别:private、protected、public和(如果没有指定)package。
访问级别
Private:类
无说明符:类、包
Protected:类、包、子类
Public:类、包、子类、所有类
实例和类成员的初始化
可以在声明的同时进行初始化,但是有一些限制:
– 必须以一个赋值语句表达初始化方式
– 初始化表达式不能调用任何被声明为抛出非运行时异常的方法
– 如果初始化表达式调用一个抛出运行时异常的方法,那么它不能进行错误恢复
使用静态初始化块初始化类成员;
实例成员的初始化。
覆盖和隐藏方法
覆盖(override)(实例方法):
– 子类中的 个实例方法与超类中的实例方法具有相同的标记和返回类型
– 方法的标记:名称,参数数量、参数类型
– 覆盖方法可以具有不同的throws子句
– 覆盖方法的访问说明符允许访问限制只能比被覆盖方法的多
– 子类不能覆盖超类中声明为final的方法
– 子类必须覆盖超类中声明为abstract的方法,否则子类本身必须是抽象的
覆盖和重载(overload);
覆盖和隐藏(类方法)。
隐藏成员变量
在类中,如果一个成员变量与超类中的成员变量同名(即使它们的类型不同),那么它隐藏超类成员变量;
在子类中,不能通过简单名称引用超类中的成员变量,而是必须通过super访问它;
代码可读性差,不建议隐藏成员变量。
使用super
使用super调用被覆盖的方法;使用super调用被隐藏的成员变量;使用super在构造器中调用超类的构造器。
使用Object的后代
每个类都是Object类的直接后代或间接后代;
Object类定义了所有类都必须有的基本状态和行为:
– clone
– equals和hashCode
– finalize
– toString
– getClass
– notify、notifyAll和wait
编写final类和方法
将类声明为final,即类不能被子类化:
– 通过防止系统被改版来提高系统的安全性
– 出于设计上的原因,某些类不需要子类
final方法:
– 在方法声明中使用final关键字表示这个方法不能被子类覆盖
编写抽象类和方法
抽象类:
– 表示一个抽象的概念,不应该被实例化
– abstract关键字
抽象方法:
– 没有实现的方法,允许子类提供这些方法的实现细节
– 如果抽象类只包含抽象方法,那么它应该被定义成接口
创建类的小结
类的定义有两个部分:
– 类声明
– 类体:成员变量、方法、构造器
访问说明符——控制对成员变量和方法的访问方式;
类变量、类方法,static方法关键字
实例成员、实例方法
五、接口和包
实现接口:implements关键字
类可以实现多个接口,implements关键字后面跟以逗号分隔的接口列表;
如果有extends关键字,implements子句应该在extends子句的后面;
类要么必需实现接口及其超接口中的所有方法,要么类必须被声明为抽象的;
类中的方法标记(名称和参数列表)必须匹配接口中的方法标记。
将接口作为类型使用
在定义了一个新接口是,就是在定义一个新的引用数据类型;
定义可一用接口,实例化是必须用类。
接口不能改变
从语法的角度看,接口可以被改变;
从设计的角度看,一个已经在系统中被广泛使用的接口,不能轻易被改变;
如果改变了接口,实现原接口的类都将无法工作;
应该尽可能的考虑接口所提供的方法;
如果要改变接口,用继承的方式定义新的接口。
接口小结
接口定义了一种功能描述,定义了对象之间进行通讯的协议;
接口定义由接口声明和接口体组成;
接口包含一组方法的声明,但没有方法的实现;
实现接口的类必须实现接口中声明的所有方法;
接口名称可以作为数据类型使用。
创建和使用包
创建包:
– 将package语句作为类或接口源代码文件中的第一条语句
– 类或接口的源代码和类文件的路径名与包的名称相对应
使用另一个包中的接口或类:
– 类或接口的限定名
– 导入类或接口
– 导入类或接口所在的整个包
六、使用异常处理错误
什么是异常:异常(exception)是在程序执行期间中断指令的正常流程的事件。
try块
try {
statements
}
statements是包含一个或多个可能抛出异常的语句。
catch块
每个catch块是一个异常处理器,它处理由其参数指定的异常类型
try{
......
} catch(ExceptionType name) {
……
} catch (ExceptionType name) {
……
}
finally块
finally块是可选的,它提供一种机制,其目的是无论try块中是否发生异常都确保进行清理工作;
无论是否发生异常,都会执行finally块中的代码。
throw语句
throw语句需要一个参数:一个可抛出的(Throwable)对象;可抛出对象是Throwable类的子类。
Throwable类及其子类
Throwable类有两个直接子类:
– Error
– Exception
Error:
– JAVA虚拟机的动态链接故障或其它“硬”故障,一般的程序不应该捕获Error,也不能抛出Error
Exception:
大多数程序抛出并捕获从Exception类派生的对象。Exception表示发生了一个问题,但并不是严重的系统问题。你写的多数程序将抛出并捕获Exception(而不是Error)。
– Exception表示发生了一个问题,但并不是严重的系统问题
– Exception的不同子类表示可能发生的各种异常
异常的优点:将错误代码与“常规”代码分离;将错误沿调用堆栈向上传递;对错误类型进行分组和区分。
异常的小结
程序可以使用异常表明发生了错误;
程序可以使用throw语句抛出异常;
异常是一个对象(Throwable的子类);
程序可以使用try、catch语句finally来捕获异常:
– try语句标识出可能发生的异常
– catch语句标识出异常处理器
– finally代码块不论抛出异常与否都会被执行,适用于清理工作
七、线程:同时执行多个任务
只要用到线程就必须继承或接口:Thread。
只要用到线程就必须要用run方法。
什么是线程:
– 线程是程序内的一个单一的顺序控制流程
– 线程本身不是程序,不能单独运行,它在一个程序内运行
– 多个线程可以同时运行,在一个程序内执行不同的任务
定制线程的run方法
run方法执行线程的工作;
run方法实现了线程的运行行为;
run方法可以做任何可以用语句实现的事。
为线程提供run方法:
– 继承Thread类,并覆盖run方法
– 实现Runnable接口
对Thread类进行子类化和覆盖run
public class SimpleThread extends Thread {
public SimpleThread(String str) {
super(str);
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
sleep((long)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
}
}
实现Runnable接口:如果一个类已经继承了另一个类,那么要想实现线程就必须实现Runnable接口。
在线程中结果是随机产生的,如果想锁定对象就要使用Synchronized关键字意思为锁定方法所有在的对象。在对象被解锁前,其他线程不能调用相同对象上的被同步的方法。意思为执行一个对象后激活另一个对象,自身暂时睡眠,等待另一个对象执行完毕,在执行下一步,反复如此。
八、IO:读和写
如何使用管道流:管道用于将一个线程的输出连接到另一个线程的输入
如何封装流:流经常被以下的这种形式封装起来,以便组合许多流的各种功能
对象的串行化:Java.io包中的两个流——ObjectInputStream和ObjectOutputStream是字节流,他们的工作与其他输入和输出流类似。但他们的特殊之处在于它们可以读写对象。
对对象进行串行化:如果将一个不能串行化的对象传递给writeObject方法,那么它抛出一个NotSerializable Exception。对象只能在它的类实现了Serializable接口的情况下被串行化。
为类提供对象串行化:只有在对象的类实现了Serializable接口情况下,对象才是可串行化的。所有,如果想要对你的类的实例进串行化,这个类必须实现Serializable接口。Serializable接口是一个空接口,也就是说,他不包含任何方法声明;它的作用只是表明这个类的对象可以被串行化。
I/O复制小程序(Copy.java),如下:
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//以上是此程序用到的IO类的包,也可以用“import java.io.*”
public class Copy {
public static void main(String[] args) throws IOException {
File inputFile = new File("D:\\temp\\HelloWorld.java"); //目标文件路径,JAVA中路径地址只能用“\\”或“/”不能使用“\”
File outputFile = new File("D:\\temp\\OutAgain.java"); //复制后新文件保存路径
FileReader in = new FileReader(inputFile);
FileWriter out = new FileWriter(outputFile);
int c;
while ((c = in.read()) != -1) //一直循环到0表示已经复制完毕,所以这里使用不等于负1
out.write(c);
in.close(); //关闭读文件对象
out.close(); //关闭写文件对象
}