Java 面向对象
1. static 和 final
static关键字---修饰成员变量
用static修饰的成员变量不属于对象的数据结构。
static变量是属于类的变量,通常可以通过类名来引用static成员。
static成员变量和类的信息一起存储在方法区,尔不是在堆中。
一个类的static成员变量只有一份,无论创建了多少对象。
static关键字---修饰成员变量的意义
class Cat {
private int age;
private static int numOfCats;
public Cat(int age) {
this.age = age;
System.out.println(++numOfCats);
}
}
Cat cat = new Cat(5); //1
Cat cat1 = new Cat(5); //2
static关键字---修饰方法
通常的方法都会涉及到具体对象的操作。这些方法在调用时,需要隐式的传递对象的引用。
int d = p1.distance(p2);
static修饰的方法则不需要针对某些对象进行操作,其运行结果仅仅与输入的参数有关。调用时直接用类名调用。
double c = Math.sqrt(3.0*3.0+4.0*4.0);
static关键字---修饰方法的意义
由于static在调用时没有具体的对象,因此static方法中不能非static成员进行访问。static方法的作用在于提供一些“工具方法”和“工厂方法”等。
静态方法属于类的方法。
final关键字---修饰类
final关键字修饰的类不可以被继承。
final关键字---修饰方法
final关键字修饰的方法不可以被重写
final关键字---修饰成员变量
final关键字修饰成员变量,意为不可改变。该成员变量需要在初始化时赋值,对象一旦创建即不可改变。
2.对象数组
所谓对象数组,是对象的元素不是基本类型,而是引用类型。
对象数组的初始化
与基本类型数组的初始化方式一样,只不过元素是对象引用而已。
但需要注意:基本类型数组元素有默认初始值;而对象数组创建后,其元素的默认值为null,不创建元素对象。
Cat[] cats = new Cat[4];
System.out.println(Arrays.toString(cats)); //[null, null, null, null]
数组类型数组(二维数组)
数组的元素可以为任何类型,也包括数组类型。
int[][] arr4 = new int[3][];
arr4[0] = new int[2];
arr4[1] = new int[4];
arr4[2] = new int[2];
arr4[1][1] = 100;
3.抽象类
什么是抽象类
用abstract关键字修饰的类称为抽象类。抽象类不能实例化,抽象类的意义在于“被继承”。抽象类为其子类“抽象”出了公共的部分,通常也定义了子类所必须具体实现的抽象方法。
public abstract class Shape {
//一个类如果定义有抽象方法必须以abstract关键字声明为抽象类,
private int x;
private int y;
public abstract boolean contanins(int x,int y);
//用abstract修饰的方法,称之为抽象方法,抽象方法仅有方法的定义,没有实现。
}
继承抽象类
一个类继承抽象类必须实现其抽象方法。
4.Timer和TimerTask简介
JDK提供的Timer和TimerTask抽象类可以以固定的周期运行某段时间。其中Timer常用的schedule方法如下:
schedule(TimerTask task,long delay,long period);
class MyTask extends TimerTask {
@Override
public void run() {
System.out.println("MyTask...");
}
}
Timer time = new Timer();
time.schedule(new MyTask(),1000,500);
time.cancel();
4.接口
什么是接口
接口可以看成是特殊的抽象类。即只包含有抽象方法的抽象类,例
interface Runner { //通过interface关键字定义接口
//接口中不能定义成员变量,但可以定义常量
public static int DEFAULT_SPEED = 100;
//接口中只能定义没有实现的方法(可以省略public abstract)。
public void run();
}
接口的实现
与继承不同,一个类可以实现多个接口,实现的接口直接用逗号分隔,该类需要实现这些接口中定义的所有方法。
接口可以作为一个类型声明变量,一个接口类型的变量可以引用实现了该接口的类的对象;通过该变量可以调用该接口中定义的方法。
class AmericanCurl implements Runner{
public void run(){
System.out.println("run...");
}
}
Runner runner = new AmericanCurl();
runner.run();
接口的继承
接口间存在继承关系,一个接口可以通过extends关键字继承另一个接口。子接口继承了父接口中定义的方法。
interface Hunter extends Runner {
public void hunt();
}
class AmericanCurl implements Hunter {
public void hunt() {
System.out.println("hunt...");
}
public void run() {
System.out.println("run...");
}
}
4.内部类和匿名类
内部类的定义
一个类可以定义在另一个类的内部,定义在类内部的类称之为Inner,其所在的类称之为Outer。
class Outer {
private int time = 100;
private Timer timer = new Timer();
public void start() {
timer.schedule(new Inner(),1000,500);
}
public void print() {
System.out.println(time);
}
//Inner定义在Outer的内部通常只服务于Outer,对外部具备可见性;Inner可以直接调用Outer的成员变量及方法。
class Inner extends TimerTask {
public void run(){
time++;
print();
}
}
}
内部类的应用
当一个类存在的价值仅仅是为某一个类服务时,应当使其成为那个类的内部类。
内部类一般情况下对外不可见,除了包含它的外部类外,其他类无法访问到它。
内部类可以很方便的访问其外部类的私有属性。
匿名内部类的定义
如果在一段程序中需要创建一个类的对象,而对象创建后,这个类的价值就不存在了,这个类可以不必命名,称之为匿名内部类。
匿名内部类的应用
匿名内部类应用在接口回调、事件监听等场合。
5.回调模式
回调模式是指---如果一个方法的参数是接口类型,则在调用改方法时,需要创建并传递一个实现此接口类型的对象;而该方法在运行时会调用到参数对象中所实现的方法。
public static void main(String[] args) {
reprat(5, new Action() {
@Override
public void doSth() {
System.out.println("Hello word");
}
});
}
public static void reprat(int n,Action action){
for (int i = 0; i < n; i++) {
action.doSth();
}
}
interface Action {
public void doSth();
}
6.事件监听机制
事件监听可以看成回调模式在Swing组件响应用户事件中的应用。
7.ActionListener
ActionListener一般用于监听表示要开始某种操作的事件,如:按钮的单击,文本框输入回车等。
public interface MouseListener extends EventListener {
public void mouseclicked(MouseEvent e);
public void mousePressed(MouseEvent e);
public void mouseReleased(MouseEvent e);
public void mouseEntered(MouseEvent e);
public void mouseExited(MouseEvent e);
}
MouseEvent的getX()、getY()方法可以获取鼠标在事件源区域点击的位置,
getButton()`方法可以判断鼠标点击的左键还是右键;getClickCount()可以判断是单击还是双击。
8.KeyListener
KeyListener用于监听键盘事件,其中包括键按下、键释放以及键入的事件。
public interface KeyListener extends EventListener {
public void keyTyped(KeyEvent e);
public void keyPressed(KeyEvent e);
public void keyReleased(KeyEvent e);
}
用getKeyCode()
方法用于获取按下(释放)的键值。
9.Listener和Adapter
在一些场合,仅仅需要响应Listener的某些方法,但作为实现Listener接口的对象又不得不实现其所有的方法,尽管某些方法只有空的实现。
JDK对某些Listener提供了相应的Adapter,即实现了改Listener接口,而所有方法都为空实现的抽象类。在使用中,只需要继承该抽象类,重写需要的方法即可。
public abstract class KeyAdapter implements KeyListener {
public void keyTyped(KeyEvent e){
//空实现
};
public void keyPressed(KeyEvent e){
//空实现
};
public void keyReleased(KeyEvent e){
//空实现
};
}