抽象类的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| public abstract class Logger { private String name; private boolean enabled; private Level minPermittedLevel; public Logger(String name, boolean enabled, Level minPermittedLevel) { this.name = name; this.enabled = enabled; this.minPermittedLevel = minPermittedLevel; } public void log(Level level, String message) { boolean loggable = enabled && (minPermittedLevel.intValue() <= level.intVal) if (!loggable) return; doLog(level, message); } protected abstract void doLog(Level level, String message); }
public class FileLogger extends Logger { private Writer fileWriter; public FileLogger(String name, boolean enabled, Level minPermittedLevel, String filepath) { super(name, enabled, minPermittedLevel); this.fileWriter = new FileWriter(filepath); } @Override public void doLog(Level level, String mesage) { fileWriter.write(...); } }
public class MessageQueueLogger extends Logger { private MessageQueueClient msgQueueClient; public MessageQueueLogger(String name, boolean enabled, Level minPermittedLevel, MessageQueueClient msgQueueClient) { super(name, enabled, minPermittedLevel); this.msgQueueClient = msgQueueClient; } @Override protected void doLog(Level level, String mesage) { msgQueueClient.send(...); } }
|
抽象类不允许被实例化,只能被继承。也就是说,你不能 new 一个抽象类的对象出来 (Logger logger = new Logger(…); 会报编译错误)。
抽象类可以包含属性和方法。方法既可以包含代码实现(比如 Logger 中的 log() 方 法),也可以不包含代码实现(比如 Logger 中的 doLog() 方法)。不包含代码实现的 方法叫作抽象方法。
子类继承抽象类,必须实现抽象类中的所有抽象方法。对应到例子代码中就是,所有继 承 Logger 抽象类的子类,都必须重写 doLog() 方法。
接口的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public interface Filter { void doFilter(RpcRequest req) throws RpcException; }
public class AuthencationFilter implements Filter { @Override public void doFilter(RpcRequest req) throws RpcException { } }
public class RateLimitFilter implements Filter { @Override public void doFilter(RpcRequest req) throws RpcException { } }
public class Application { private List<Filter> filters = new ArrayList<>(); public void handleRpcRequest(RpcRequest req) { try { for (Filter filter : fitlers) { filter.doFilter(req); } } catch(RpcException e) { } } }
|
接口不能包含属性(也就是成员变量)。
接口只能声明方法,方法不能包含代码实现。
类实现接口的时候,必须实现接口中声明的所有方法.
区别
接口和抽象类,他们要解决的问题不一样 ,首先接口是为了解耦,而抽象类是为了减少编写重复的代码。
比如说类A和类B都要写一个方法doSomething,那么就可以写一个抽象类,然后A和B都继承该抽象类,而且类A和B可以各自添加各自的功能。
而接口的解耦体现在,我们定义一个接口之后,他可以有多个实现,我们基于他不同的实现来达到对于模块的划分,隔离接口和具体的实现,提高代码的扩展性。
参考
《设计模式之美》