接口和抽象类的区别
接口
- 接口是对行为的抽象,它是抽象方法的集合,利用接口可以达到
API
定义和实现分离的目的。 - 有一类没有任何方法的接口用作标志,比如
Serializable
接口就表示这个类可以被序列化 - 不能实例化;
- 不能包含任何非常量成员,任何
field
都是隐含着public static final
的意义; - 没有非静态方法实现,也就是说要么是抽象方法,要么是静态方法。
Java
类实现interface
使用implements
关键词Java 8
以后增加了默认方法。在方法签名前加上default
。它可以为接口添加新的方法,而不会破坏已有的接口的实现。Java 8
新增了函数式接口,接口内只含有一个抽象方法。通常使用@FunctionalInterface Annotation
。Lambda
表达式只能用于函数式接口
抽象类
- 抽象类是不能实例化的类,用
abstract
关键字修饰class
, - 其目的主要是代码重用。除了不能实例化,形式上和一般的
Java
类并没有太大区别,可以有一个或者多个抽象方法,也可以没有抽象方法。 - 抽象类大多用于抽取相关
Java
类的共用方法实现或者是共同成员变量,然后通过继承的方式达到代码复用的目的。 - 继承
abstract class
则是使用extends
关键词
面向对象基础
基本要素
最后一个示例实在让我有些惊讶,从没注意过这些东西,就将他们全部复制下来了
OOP 原则在面试题目中的分析
我在以往面试中发现,即使是有多年编程经验的工程师,也还没有真正掌握面向对象设计的基本的原则,如开关原则(Open-Close)。看看下面这段代码,改编自朋友圈盛传的某伟大公司产品代码,你觉得可以利用面向对象设计原则如何改进?
public class VIPCenter {
void serviceVIP(T extend User user>) {
if (user instanceof SlumDogVIP) {
// 穷X VIP,活动抢的那种
// do somthing
} else if(user instanceof RealVIP) {
// do somthing
}
// ...
}
这段代码的一个问题是,业务逻辑集中在一起,当出现新的用户类型时,比如,大数据发现了我们是肥羊,需要去收获一下, 这就需要直接去修改服务方法代码实现,这可能会意外影响不相关的某个用户类型逻辑。利用开关原则,我们可以尝试改造为下面的代码:
public class VIPCenter {
private Map<User.TYPE, ServiceProvider> providers;
void serviceVIP(T extend User user) {
providers.get(user.getType()).service(user);
}
}
interface ServiceProvider{
void service(T extend User user) ;
}
class SlumDogVIPServiceProvider implements ServiceProvider{
void service(T extend User user){
// do somthing
}
}
class RealVIPServiceProvider implements ServiceProvider{
void service(T extend User user) {
// do something
}
}
上面的示例,将不同对象分类的服务方法进行抽象,把业务逻辑的紧耦合关系拆开,实现代码的隔离保证了方便的扩展。