为什么有抽象类还要接口
1概述
接口提供的是统一的规范,供内部系统或外部系统调用。
抽象类具有接口的特性,同时还可以有自己的默认实现。
2惯用方法
2.1定义接口
package JavaBasic.MyInterface;
/**
* Created by kikop on 2017/11/19.
*/
public interface IElement {
//接口的共用方法
//减少类之间的依赖关系,依赖第三方类,这里引入接口。
public void accept(AbsVisitor absVisitor);
}
2.2定义抽象类
package JavaBasic.MyInterface;
import java.util.Iterator;
/**
* Created by kikop on 2017/11/19.
*/
public abstract class AbsEntry implements IElement {
//1.抽象类的抽象方法
public abstract String getName();
//2.抽象类的默认实现
public Iterator iterator() throws FileException {
throw new FileException();
}
public void myDefaultImp() {
System.out.println("这是我的默认实现!");
}
//3.公共方法
public String toString() {
return getName();
}
}
2.3定义实现
package JavaBasic.MyInterface;
/**
* Created by kikop on 2017/11/19.
*/
public class MyFile extends AbsEntry {
public String name;
@Override
public String getName() {
return name;
}
@Override
public void accept(AbsVisitor absVisitor) {
System.out.println("实现接口中的方法!");
}
}
2.4测试
/**
* 惯用方法(接口和抽象类)
*/
@Test
public void testInterfaceAndAbs() {
MyFile myFile = new MyFile();
AbsVisitor absVisitor = null;
myFile.myDefaultImp();
myFile.accept(absVisitor);
}
3只使用抽象类
3.1定义抽象类
package JavaBasic.MyInterface;
import java.util.Iterator;
/**
* Created by kikop on 2017/11/19.
*/
public abstract class AbsEntry2 {
//1.抽象类的抽象方法
public abstract String getName();
public abstract void accept(AbsVisitor absVisitor);
//2.抽象类的默认实现
public Iterator iterator() throws FileException {
throw new FileException();
}
public void myDefaultImp() {
System.out.println("这是我的默认实现!");
}
//3.公共方法
public String toString() {
return getName();
}
}
3.2定义实现
package JavaBasic.MyInterface;
/**
* Created by kikop on 2017/11/19.
*/
public class MyFile2 extends AbsEntry2 {
public String name;
@Override
public String getName() {
return name;
}
@Override
public void accept(AbsVisitor absVisitor) {
System.out.println("实现抽象类中的抽象方法!");
}
}
3.3测试
/**
* 只有抽象类
*/
@Test
public void testAbsOnly() {
MyFile2 myFile = new MyFile2();
AbsVisitor absVisitor = null;
myFile.myDefaultImp();
myFile.accept(absVisitor);
}
4只使用接口
4.1定义接口
package JavaBasic.MyInterface;
import java.util.Iterator;
/**
* Created by kikop on 2017/11/19.
*/
public interface IEntry {
//1.抽象类的抽象方法
public String getName();
public void accept(AbsVisitor absVisitor);
public Iterator iterator() throws FileException;
public String toString();
//2.抽象类的默认实现
// public Iterator iterator() throws FileException {
// throw new FileException();
// }
// public void myDefaultImp() {
// System.out.println(“这里无法有默认实现!”);
// }
//3.公共模板方法无法使用
// public String toString() {
// return getName();
// }
}
4.2定义实现类
package JavaBasic.MyInterface;
import java.util.Iterator;
/**
* Created by kikop on 2017/11/19.
*/
public class MyFile3 implements IEntry {
public String name;
@Override
public String getName() {
return name;
}
@Override
public void accept(AbsVisitor absVisitor) {
System.out.println("实现抽象类中的抽象方法!");
}
//2.抽象类的默认实现
public Iterator iterator() throws FileException {
throw new FileException();
}
//3.公共模板方法无法使用
public String toString() {
return getName();
}
}
4.3测试
/**
* 只有接口
*/
@Test
public void testInterfaceOnly() {
MyFile3 myFile = new MyFile3();
AbsVisitor absVisitor = null;
//myFile.myDefaultImp();
myFile.accept(absVisitor);
}
5总结
不管使用哪一种,都能实现我们的目的。
经过上面的实践,我们发现如果只使用接口,会导致在实现类中代码重复,如这里的ToString、GetName等。
只使用抽象类,代码上面没有多出,但是对外统一的接口无法一目了然,如这里的accept,特别是需要进行数据结构与逻辑处理分开时,v的参数是重载的实现类。
结合两者优点,最终达到:结构清晰,减少耦合,扩展和维护性增强。