Java笔记-抽象类和接口的区别

Java笔记-抽象类和接口的区别

1、概念

抽象类

  • 如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
  • 抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样
  • 由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。
  • 在Java语言中使用abstract class来定义抽象类。
  • 在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

抽象类不能实例化

 

 抽象方法

  • 如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法
  • Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体
  • 抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。
    public abstract String eat();
    //抽象方法

    public String sleep(){
        return "sleep";
    }

 

注意:

  • 如果一个类包含抽象方法,那么该类必须是抽象类
  • 任何子类必须重写父类的所有抽象方法,或者声明自身为抽象类。普通成员方法不必须重写。
  • 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。 
  • 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

 

 例子

/**
 * @author HP
 * @data 2021-01-28
 * Pig抽象类
 */
public abstract class Pig {
    
    private String name;

    public abstract String eat();
    //抽象方法

    public String sleep(){
        return "sleep";
    }

    @Override
    public String toString() {
        return "Pig{" +
                "name='" + name + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 

/**
 * @author HP
 * 继承Pig类
 */
public class Paige extends Pig {

    @Override
    public String eat() {
        return "eat";
    }

    public static void main(String[] args) {
        Paige paige = new Paige();
        paige.setName("paige");
        System.out.println(paige.eat());
        System.out.println(paige.sleep());
        System.out.println(paige.toString());

    }
}

 

输出结果

 

接口

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。

 

 重写方法

        paige.shout();
    }

    @Override
    public void shout() {
        System.out.println("shout");
    }

 

  • 接口可以多继承
  • 接口的方法声明必须是 public abstract 即便不写默认也是
  • 接口里面不能包含方法具体实现
  • 类实继承接口必须实现接口里申明的全部方法,除非该类是抽象类
  • 类里面可以声明 public static final 修饰的变量
  • 接口不能被实例化,但是可以被实现类创建
  • 静态方法只能通过接口名调用,不可以通过实现类的类名或者实现类的对象调用(Java8)
    static void fly() {
        System.out.println("fly");
    }


    Shout.fly();
    //静态方法——>输出fly

 

2、异同点

相同

  • 不能实例化
  • 都可以实现方法(java8以前的接口不能实现方法)
  • 需要重写abstract方法

不同

  • 设计理念不同。抽象类表示对对象/类的抽象,接口表示对行为的抽象。
  • 抽象类不可以多重继承,接口可以多重继承;也就是说一个实现类不可以继承多个抽象类,但是可以继承多个接口。
  • 抽象类可以有构造器,接口没有。
  • 在抽象类中可以写非抽象的方法,从而避免在子类中重复书写他们,这样可以提高代码的复用性,这是抽象类的优势;接口中只能有抽象的方法。

 

访问修饰符不同

  • 抽象类的抽象方法可以用public protected 和 default abstract 修饰符;不能用private、static、synchronize、native 修饰;变量可以在子类重新定义,也可以重新赋值;
  • 接口的方法默认修饰符是 public abstract, Java8 开始出现静态方法,多加 static 关键字;变量默认是 public static final 型,且必须给其初值,在实现类中也不能重新定义,也不能改变其值。

 

3、个人理解

  • 如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。
  • 继承是一个 "是不是"的关系,如果一个类继承了某个抽象类,则子类必定是抽象类的种类,比如佩奇是属于猪这个抽象类。
  • 而接口实现则是有没有、具备不具备的关系,比如佩奇可以实现shout这个行为,就实现这个行为接口,否则不实现。

 

4、参考资料

https://www.runoob.com/java/java-abstraction.html

https://www.runoob.com/java/java-interfaces.html

posted @ 2021-01-28 20:30  秃头不用洗发水  阅读(269)  评论(0)    收藏  举报