这两个概念是面试时经常被问到的,而且工作中经常需要使用到,现在就来整理一下,供以后学习使用。
一、抽象类
1.定义 Abstract Class?
理解一:用abstract修饰的含有抽象方法的类。
理解二:声明方法的存在而不去实现它的类。
2.测试
public abstract class test {
public test am;//可以有抽象类类型变量
public test(){ } //构造方法
//方法测试
public abstract void DD();//OK
abstract void DDD();//OK
void DD0();//抽象方法必须用abstract修饰
private abstract void DD1();//不能是私有的抽象方法
public abstract static void DD2();//不能有抽象静态方法
public abstract native void DD3();//不能有抽象native方法
public abstract synchronized void DD4();//不能有抽象同步方法
//普通方法
public void D(){
System.out.println("====普通方法======");
}
}
总结:抽象类和它的抽象方法必须由abstract修饰,而且抽象方法只能是公共的(或默认)方法。当子类继承父类时,子类一定要重写父类中的全部抽象方法。
3.思考?
抽象类可以被实例化吗?
不能。实例化的是他的实现类(即子类),如:List li =new ArrayList();
二、接口
1.定义Interface?
理解一:一个对象应该具有哪些公共的操作方法。
理解二:公共方法的集合。
2.测试
2.1 JDK1.7及其以下版本测试:
------>哪些修饰符可以修饰接口?
//default修饰
interface Test_thread {
}
//public修饰
public interface Test_thread {
}
//protected修饰
protected interface Test_thread {
}
//private修饰
private interface Test_thread {
}
//static修饰
public static interface Test_thread {
}
Static、Private与protected修饰接口会报以下错误:
**结论:**修饰接口的修饰符可以用默认default,public,abstract修饰,不能用private、protected修饰。
Static是用来修饰方法,变量的,不能修饰接口,类!
------>哪些修饰符可以修饰接口中的方法?
//修饰接口方法
public interface Test_thread {
void syso();
public int getValue();
public abstract void run();
private double price();//error
protected float score();//error
public static void cart();//error
}
总结:修饰接口抽象方法的修饰符可以用默认default,public,abstract修饰,不能用private、protected修饰,static不能修饰抽象方法。
------>哪些修饰符可以修饰接口中的成员变量?
//修饰接口的成员变量
public interface Test_thread {
int a0;//error
public int b0;//error
int a=1;
public int b=2;
public final int c=3;
public static int d=4;
public static final int e=5;
}
**总结:**修饰接口抽象方法的修饰符可以用默认,public,final,static修饰,成员变量必须赋初值。不能用private、protected修饰。
注意:1.7及其以下版本的java语法规定:定义一个接口时,所有方法都必须是抽象方法,用implements实现该接口时需要重写所有的抽象方法。
2.2 JDK1.8版本对接口进行了增强
------>Java8新特性:
Java8包含了很多新的特性,可以简化开发,提升代码的可读性。重要的一些特性有:接口增强,方法引用,Stream,Lambda表达式等等。其中还有一些其他的特性,比如注解的更新,以及一些新的API等。以上四个特性在java8的开发中会比较常用。因为接口增强特性比较独立,而其他三个特性或多或少都有关联关系。
------>接口增强:
JDK1.8之前定义一个接口,它的所有方法都是抽象方法,不能去实现。但是1.8及其以后,定义一个接口,可以在里面写具体的方法,与以前接口里只有属性和抽象方法相比,接口的功能明显增强。
------>如何在接口中定义具体的方法实现?
**说明:**接口中定义具体的方法实现是有限制的,它不能像我们在一个普通类那样随便定义方法实现,它只能定义default和static类型的方法。除了关键字修饰,其他跟普通的方法定义并没有什么不同。
interface MyInterface {
public void print();
// default 和 static 方法的出现为了解决实现该接口的子类代码重复的问题
default void defaultMethod() {
System.out.println("default method invoked! ");
}
default int add(int a, int b){
return a + b;
}
static void staticMethod() {
System.out.println("static method invoked! ");
}
static int multiply(int a, int b){
return a * b;
}
}
------>接口方法的调用
public class InterfaceTest {
public static void main(String[] args) {
//调用抽象方法
MyInterface msg = new InterfaceImpl();
msg.print();
//调用有方法体的方法
msg.defaultMethod(); //调用default方法
MyInterface.staticMethod();//调用static方法
}
}
总结:
1)default方法调用
定义一个类实现该接口,new该类的实例,调用即可。
2)static方法调用
类名.方法名() 调用,这跟以前的静态方法调用方式一样。
3.思考?
接口增强的实际应用好处?
当多个类实现一个接口的某个方法时,方法的具体实现代码相同,这样就会造成代码重复问题。接口增强就相当于把公共的代码抽离出来,放入接口定义中,这样实现类对于该方法就不用重新定义,直接调用即可,这很好的解决了实现该接口的子类代码重复的问题。
三、抽象类与接口的区别?总结一下
1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2、抽象类要被子类继承extends,只能是单继承,接口要被类实现implements,接口可以继承多个接口。接口是设计的结果 ,抽象类是重构的结果。
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现。
4、接口里定义的变量默认是是公共的静态的最终的常量,抽象类中的变量是普通变量。接口中无构造方法,抽象类有。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。