接口
接口是为了实现java的“对修改封闭,对扩展开放 ”原则,某个对象声明了某个接口类方法,它便具备接口的功能,把功能部分封装出来,自然很好扩展。
例如,某个类要使用排序,但排序一定有比较大小。于是该类一定要实现Comparable接口中的Compare接口,才能使用Sort方法。
使用接口的示例:
1. 定义1个接口 interface,规定某些功能;
2. 在需要使用接口功能的类A里,声明 implement 该接口;
3. 在类A里,实现该接口;
4. 类A的对象a可以使用该接口的方法;
一些规则:
1. 接口类不能直接new ,但可以引用实现了该接口的类
class A implements Comparable {...}
Comparable comp;
comp = new A(); //接口引用方式
- 检查某个对象是否实现了特定接口
if (anObject instanceof Comparable) {...}
- 可以扩展接口:
public interface subComparable extends Comparable
- 接口不能包含实例域或静态方法,但是可以包含final常量,实现该接口的类都继承了这些常量。
- 可以实现多个接口,这也是为什么不使用抽象类而要用接口的一个原因,继承抽象类的类就固定了。
class A implements Cloneable,Comparable
拷贝与克隆
A a = new A();
b= a;//拷贝
c = a.clone();//克隆
b是a的拷贝(java中叫做引用更合适),a的内容变化,b跟着变化;JAVA中的”=”不是C++中的符号重载的”=”,更不是C中的”memcpy”。
浅克隆、深克隆
如果a中引用了其他对象,则b与a共享子对象,是浅克隆,b连子对象都拥有1份独立的是深克隆;深克隆需要重写clone()方法;越复杂的类越难搞,所以clone并不是什么友好的东西。
在使用clone前,需要申明Cloneable
接口,并用public
访问修饰符重新定义clone方法。Cloneable
属于JAVA中的标记接口,并不需要实现具体方法。
对于每个类,都需要作出以下判断:
1. 默认的clone方法是否满足要求;
2. 默认的clone方法是否能通过调用可变子对象的clone得到修补;
3. 是否不应该使用clone。
内部类
内部类是定义在另1个类中的类,类似C++中的嵌套;
class A
{
int n;
int functiona(int a)
public class B
{
int m;
int functionb(){
m = m + n ; //在B中可以直接访问自身或创建它的外围对象的数据域
public class implements xxListener {
functiona(n);//实现某lisnter,可以更方便使用A中的域和方法
}
}
}
A a = new A();
局部类
把类的实现放在某个方法里,可以访问外部类和方法的局部变量,不过局部变量要加Final关键字。显然Final的东西就不能改了,如果要修改局部变量值,可以把局部变量定位为1个数组 Final int[] a = new int[1],数组是final了,但数组的内容可以改变。
public void function(final int a ,final int b)
{
final int c = new int[1];
private class A{
c = a + b;
}
}
匿名内部类
只创建类的1个对象,new出了这个接口类的实例,需要实现的方法定义在{}内。
Listener a = new Listener(){
public void function(){...}
}
何为匿名?按正常的做法应该是
classA implements Listener
{
void function(){...}
}
Listener ls = new classA(); //本来该这么用
显然classA在匿名类使用中不用出现了,更简洁和好理解。