任何事物出现必定是有它自己的作用,要是作用原理都一样,那就没有出现的必要了。
情景一:
一般在处理后端业务逻辑的时候,往往在相同部分的业务逻辑我们需要包装,比如说请求报文头部,固定参数。但是往往也会有变化的参数。比如:
像这种我们通常采用抽象类加上抽象方法,有不变,一级变化1次,二级变化n次。怎么写呢?抽象类不变写一次固定头,空缺出一级变化抽象方法利用继承实现二级代码写一次,在空缺出抽象方法利用继承二级变化写n次。这样没有代码冗余。也就是说不变的我们需要提出来实现。类似于抽象工厂模式(如果加一个工厂管理子类的话,是不是有点像啦)。请看代码:
import java.util.HashMap;
import java.util.Map;
public class abs {
public static void main(String[] args) {
Map<String,Object> m1 = new HashMap<>();
Map<String,Object> m2 = new HashMap<>();
Class1 c1 = new Class1();//初始化了子类,继承xixixi父类并沿用父类的固定方法
Class2 c2 = new Class2();
m1 = c1.reList();
m2 = c2.reList();
System.out.println("class1输出:"+m1.toString());
System.out.println("class2输出:"+m2.toString());
}
}
abstract class Xixixi{//有子类共同实现的部分我们都在抽象类里实现
String head = "抽象类实现的固定头key";//抽象类里面可以初始化变量,可以是各种类型
String val = "抽象类实现的固定头value";
//给子类实现的方法,实现了的也可以被子类覆盖
protected abstract Map<String,Object> getMid();
public Map<String, Object> reList(){//抽象类可以有部分实现
Map<String,Object> mapHeader = new HashMap<>();
mapHeader.put(head,val);
Map<String,Object> mapMid = new HashMap<>();
mapMid = getMid(); //这里
mapHeader.put("继承类实现部分",mapMid);
return mapHeader;
}
}
class Class1 extends Xixixi{//变化的东西我们都在子类里实现,这样减少了代码冗余
@Override
protected Map<String, Object> getMid() {
Map<String,Object> map = new HashMap<>();
map.put("我是class1","我是class1的value");
return map;
}
}
class Class2 extends Xixixi{//变化的东西我们都在子类里实现,这样减少了代码冗余
@Override
protected Map<String, Object> getMid() {
Map<String,Object> map = new HashMap<>();
map.put("我是class2","我是class2的value");
return map;
}
}
结果:
接下来说说接口:
接口和抽象类想对比有几点值的注意:
1、一般不写变量,只能是常量。因为接口不能有变数,所以常量默认为static final型,要对外可用,所以也是默认public。
2、接口没有部分实现。实现全在实现类里。
3、接口不能有static初始化的方法以及实现。也就是不允许出现静态代码块和以及静态方法。没法实现嘛不是。
4、一个子类只能实现一个抽象类,一个实现类可以实现多个接口。java没有多继承,但是可以有多实现接口。
有看官会问了,那你这样说接口好像不好用。
实际上接口更倾向于一种规范,它使得流程清晰,合作方便,用过后端框架的同志关注过service层和impl层。其实接口可有可无,但是随着逻辑的复杂化,就能体现出接口的优势了。请看:
import java.util.HashMap;
import java.util.Map;
public class intf {
public static void main(String[] args) {
imp imp = new imp();
imp1 imp1 = new imp1();
imp3 imp3 = new imp3();
System.out.println(imp.layer1().toString());
System.out.println(imp1.layer2().toString());
System.out.println(imp3.layer1().toString());
System.out.println(imp3.layer2().toString());
}
}
interface Xixi {
Map<String, Object> layer1();
}
interface Xi {
Map<String, Object> layer2();
}
class imp implements Xixi{
@Override
public Map<String, Object> layer1() {
String head = "实现的固定头layer1";
String val = "实现的固定layer1";
Map<String, Object> mapHeader = new HashMap<>();
mapHeader.put(head, val);
return mapHeader;
}
}
class imp1 implements Xi{
@Override
public Map<String, Object> layer2() {
String head = "实现的固定头layer2";
String val = "实现的固定头layer2";
Map<String, Object> mapHeader = new HashMap<>();
mapHeader.put(head, val);
return mapHeader;
}
}
class imp3 implements Xixi,Xi{
@Override
public Map<String, Object> layer1() {
String head = "实现的固定头layer1";
String val = "实现的固定layer1";
Map<String, Object> mapHeader = new HashMap<>();
mapHeader.put(head, val);
return mapHeader;
}
@Override
public Map<String, Object> layer2() {
String head = "实现的固定头layer2";
String val = "实现的固定头layer2";
Map<String, Object> mapHeader = new HashMap<>();
mapHeader.put(head, val);
return mapHeader;
}
}
嘿嘿嘿,实际上发现两者区别或者应用场景还是由很大区别的,平时多注意下,就清楚了。嘿嘿嘿