在撰写Java程序时,经常会有临时继承某个类或操作某个接口并建立实例的需求。由于这类子类或接口操作类只使用一次,不需要为这些类定义名称,这时可以使用匿名内部类( Anonymous Inner Class)来解决这个需求。匿名内部类的语法为:
new 父类()|接口(){
//类本体操作
}
Object obj=new Object() {
@Override
public String toString() {
return "返利";
}
};
继承object重新定义toString方法。如果是操作接口如Some接口定义抽象方法doSome建立匿名内部类:
Some some = new Some(){
public void doSome(){
//执行语句
};
};
来举个接口应用的例子。假设开发多人联机程序,对每个联机客户端,都会建立client对象封装相关信息:
package clientDemo;
public class Client {
public final String ip;
public final String name;
public Client(String ip,String name) {
this.ip=ip;
this.name=name;
}
}
程序中建立的 Client对象,都会加入ClientQueue集中管理,其他部分希望在Client加入或移除时可以收到通知,以便做一些处理(例如进行日志记录),那么可以将Client加入或移除的信息包装为 ClientEvent:
package clientDemo;
public class ClientEvent {
private Client client;
public ClientEvent(Client client) {
this.client=client;
}
public String getName() {
return client.name;
}
public String getIp() {
return client.ip;
}
}
定义Client Listener接口,有对象对client加入Clientqueue统计,可以操作这个接口:
package clientDemo;
public interface ClientListener {
void clientAdded(ClientEvent event);
void clientRemoved(ClientEvent event);//默认public abstract void clientRemoved(ClientEvent event)
}
在ClientQueue新增或移除Client时通知:
package clientDemo;
import java.util.ArrayList;
public class ClientQueue {
private ArrayList<Client> clients=new ArrayList<>();//收集联机的client
private ArrayList<ClientListener> listeners=new ArrayList<>();//收集对clientqueue有兴趣的clientlistener
public void addClientListener(ClientListener listener) {//注册ClientListener
listeners.add(listener);
}
public void add(Client client) {
clients.add(client);//新增Client
ClientEvent event=new ClientEvent(client);//通知信息包装为ClientEvent
for(int i=0;i<listeners.size();i++) {//逐一取出
ClientListener listener=(ClientListener) listeners.get(i);
listener.clientAdded(event);
}
}
public void remove(Client client) {
clients.remove(client);//新增Client
ClientEvent event=new ClientEvent(client);
for(int i=0;i<listeners.size();i++) {
ClientListener listener=(ClientListener) listeners.get(i);
listener.clientRemoved(event);
}
}
}
ClientQueue会收集联机后的Client对象,( Java SE API就提供java.util.Arraylist,可以让你进行对象收集)。
如果有对象对 client加入 ClientQueue有兴趣,可以操作ClientListener并通过 addclientlistener()注册。当每个 client通过 ClientQueue的add(收集时,会用 Arraylist收集 client,接着使用 ClientEvent封装Client相关信息,再使用for循环将注册的 Clientlistener逐一取出,并调用 clientAdded()方法进行通知。如果有对象被移除,流程也是类似,这可以在 ClientQueue的 remove()方法中看到相关程序代码。
可以使用以下的程序代码使用匿名内部类,直接建立操作 ClientListener的对象:
package clientDemo;
public class MultiChat {
public static void main(String[] args) {
Client c1 = new Client("127.0.0.1","Android");
Client c2 = new Client("192.168.0.2","PC");
ClientQueue queue = new ClientQueue();
queue.addClientListener(new ClientListener() {
@Override
public void clientAdded(ClientEvent event) {
System.out.printf("%s从%s联机%n",event.getName(),event.getIp());
}
@Override
public void clientRemoved(ClientEvent event) {
System.out.printf("%s从%s脱机%n",event.getName(),event.getIp());
}
});
queue.add(c1);
queue.add(c2);
queue.remove(c1);
queue.remove(c2);
}
}
执行结果: