引言:

接口和抽象类的概念不一样。接口是对动作的抽象,抽象类是对根源的抽象。

一个类只能继承一个类(抽象类,java类的单继承,接口可以多继承)

接口是可以实现多个接口

 抽象类:

抽象类除了能象普通类一样可以拥有一般的属性和方法,也可以拥有抽象方法(abstract method) 

抽象方法与抽象的行为相对应,通常是这个行为对父对象没有意义,而子对象有具体动作。所以为了不让该类建立对象,也可以把没有抽象方法的类,定义为抽象类

抽象方法还有一个特点是,它强迫子类要么仍然保持抽象性(即不具体实现该方法并仍然定义为抽象类),要么具体表现出这个方法的行为(实现具体的动作或者通过抛出UnsupportedOperationException异常来表明不支持该行为)。这样也可以强化多态性。

抽象类不能new,因为调用抽象方法没意义.

 匿名内部类实例化

abstract class B {
    private String str;

    public B(String a) {
        System.out.println("父类已经实例化");
        this.str=a;
        System.out.println(str);
    }

    public abstract void play();
}

public class A {

    public static void main(String[] args) {
        B aa = new B("test") {
            @Override
            public void play() {
                System.out.print("B play method");
            }
        };

        aa.play();
    }

}

抽象类的确不能实例化。
这种格式(new TestAbs(){要重写的方法})叫匿名内部类,实际上是实例化一个它的子类.其实就相当于下面这样,只是匿名不匿名的区别。

class Test extends B{
    @Override
            public void play() {
                System.out.print("B play method");
            }
}
B aa = new Test();
aa.play("test");

接口:

接口中的方法都是抽象方法 (接口中一般只包含一组public抽象方法,且必须是公有抽象方法,但方法定义中public abstract可省略,也可以包含public 静态final数据)。

接口也是可以继承的,而且多继承

 

接口和抽象类的不同点

(1)抽象类可以有实例变量,而接口不能拥有实例变量(接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的),接口中的变量都是静态的常量(public static final)。

(2) 抽象类可以有非抽象方法,而接口只能有抽象方法(public abstract 默认省略)。

(3)抽象的子类可以选择性实现其基类的抽象方法,而接口的子类必须实现

(4)java允许一个接口继承(extend)多个父接口,也允许一个类实现多个接口...抽象类只能单继承..

(5)一个抽象类B可以实现另一个接口A,不需要实现A中方法...  可以认为接口比抽象类更抽象.

 

番外::::::

接口默认方法的使用

 

顾名思义,默认方法就是接口提供一个默认实现,且不强制实现类去覆写的方法。默认方法用default关键字来修饰。

默认方法可以解决的痛点:

在java8之前,修改接口功能通常会给接口添加新的方法,这时对已经实现该接口的所有实现类,都要一一添加对新方法的实现,换言之,在给接口定义新方法的同时无法不影响到已有的实现类,这时,java8的默认方法特性就可以解决这种接口修改与已有实现类不兼容的问题,比如java8中Iterable接口添加的forEach方法就是一个默认方法:

default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

2.1 实现多个接口有相同默认方法的解决

    注意:当一个类实现多个接口时,若多个接口中存在相同默认方法(方法名、参数、返回值相同),此时实现类必须要覆写默认方法

     覆写有两种方式:

  • 1、实现类自己实现方法逻辑
  • 2、采用super关键字来调用指定接口的默认方法, 如:
public interface TestInterface1
{
    default void test()
    {
        System.out.println("TestInterface1");
    }   
}

public interface TestInterface2
{
    default void test()
    {
        System.out.println("TestInterface2");
    }
}

public class Test implements TestInterface1, TestInterface2
{
    @Override
    public void test()
    {
        // 调用TestInterface1接口的默认test()方法
        TestInterface1.super.test();
    }
}

2.2.如果子类继承父类,父类中有b方法,该子类同时实现的接口中也有b方法(被default修饰),那么子类会继承父类的b方法而不是继承接口中的b方法

public class Test extends C implements A{
	
}

2.3 接口静态方法

     java8支持接口中定义静态方法(需要提供默认实现),写法上将默认方法的default关键字换成static关键字即可。