java抽象类和接口

抽象类特点

  • 抽象类和抽象方法都使用 abstract 关键字进行声明。抽象类一般会包含抽象方法,抽象方法一定位于抽象类中。
  • 抽象类和普通类最大的区别是,抽象类不能被实例化,需要继承抽象类才能实例化其子类。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public abstract class AbstractClassExample {

    protected int x;
    private int y;

    public abstract void func1();

    public void func2() {
    System.out.println("func2");
    }
    }

    public class AbstractExtendClassExample extends AbstractClassExample {
    @Override
    public void func1() {
    System.out.println("func1");
    }
    }

接口特点

  • 接口是抽象类的延伸,在 Java 8 之前,它可以看成是一个完全抽象的类,也就是说它不能有任何的方法实现。
  • 从 Java 8 开始,接口也可以拥有默认的方法实现,这是因为不支持默认方法的接口的维护成本太高了。在 Java 8 之前,如果一个接口想要添加新的方法,那么要修改所有实现了该接口的类。
  • 接口的成员(字段 + 方法)默认都是 public 的,并且不允许定义为 private 或者 protected。
  • 接口的字段默认都是 static 和 final 的。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public interface InterfaceExample {

    void func1();

    default void func2(){
    System.out.println("func2");
    }

    int x = 123;
    public int z = 0; // Modifier 'public' is redundant for interface fields
    }

    public class InterfaceImplementExample implements InterfaceExample {
    @Override
    public void func1() {
    System.out.println("func1");
    }
    }

抽象类与接口的区别

区别

  • 从设计层面上看,抽象类提供了一种 IS-A 关系,那么就必须满足里式替换原则,即子类对象必须能够替换掉所有父类对象。而接口更像是一种 LIKE-A 关系,它只是提供一种方法实现契约,并不要求接口和实现接口的类具有 IS-A 关系。
  • 从使用上来看,一个类可以实现多个接口,但是不能继承多个抽象类。
  • 接口的字段只能是 static 和 final 类型的,而抽象类的字段没有这种限制。
  • 接口的成员只能是 public 的,而抽象类的成员可以有多种访问权限。

如何选择

  • 使用接口:
    • 需要让不相关的类都实现一个方法,例如不相关的类都可以实现 Compareable 接口中的 compareTo() 方法;
    • 需要使用多重继承。
  • 使用抽象类:
    • 需要在几个相关的类中共享代码。
    • 需要能控制继承来的成员的访问权限,而不是都为 public。
    • 需要继承非静态和非常量字段。

面向对象之类名作为形式参数

  • 案例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    /*要的都是对象具体类的作为参数传递的问题*/
    class Student {
    public void show() {
    System.out.println("student.....show.............") ;
    }
    }

    class StudentDemo {
    public void method(Student s) {
    s.show() ;
    }
    }


    // 测试类
    class ArgsDemo {
    public static void main(String[] args) {
    // 创建StudentDemo的对象
    StudentDemo sd = new StudentDemo() ;
    // 创建Student的对象
    Student s = new Student() ;
    // 调用方法
    // sd.method(s) ;
    sd.method(new Student()) ;
    }
    }

面向对象之抽象类名作为形式参数

  • 案例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    /*抽象类作为参数的时候如何进行调用*/
    abstract class Animal {
    // 定义一个抽象方法
    public abstract void eat() ;
    }

    // 定义一个类
    class Cat extends Animal {
    public void eat(){
    System.out.println("吃.................") ;
    }
    }


    // 定义一个类
    class AnimalDemo {
    public void method(Animal a) {
    a.eat() ;
    }
    }

    // 测试类
    class ArgsDemo2 {
    public static void main(String[] args) {
    // 创建AnimalDemo的对象
    AnimalDemo ad = new AnimalDemo() ;
    // 对Animal进行间接实例化
    // Animal a = new Cat() ;
    Cat a = new Cat() ;
    // 调用method方法
    ad.method(a) ;
    }
    }

面向对象之接口名作为形式参数

  • 案例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    /*接口作为参数的时候我们如何进行调用*/
    interface Jump {
    // 跳高接口
    public abstract void jump() ;
    }

    // 定义一个子类
    class JumpImpl implements Jump {
    public void jump(){
    System.out.println("jump.............................") ;
    }
    }

    // 定义一个类
    class JumpDemo {
    public void method(Jump jump) {
    jump.jump();
    }
    }

    // 测试类
    class ArgsDemo3 {
    public static void main(String[] args) {
    // 1. 创建JumpDemo对象
    JumpDemo jd = new JumpDemo() ;
    // 2. 调用method方法
    // 对Jump进行间接实例化
    Jump jump = new JumpImpl() ;
    jd.method(jump) ;
    }
    }

面向对象之类名作为返回值类型

  • 案例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    /*具体类作为返回值类型*/
    class Student {
    public void show() {
    System.out.println("student....show.....................") ;
    }
    }

    // 定义一个类
    class StudentDemo {
    public Student getStudent() {
    return new Student() ;
    }
    }

    // 测试类
    class ReturnDemo {
    public static void main(String[] args) {
    // 创建StudentDemo的对象
    StudentDemo sd = new StudentDemo() ;
    // 调用 public Student getStudent()
    Student s = sd.getStudent() ;
    // 调用方法
    s.show() ;
    }
    }

面向对象之抽象类名作为返回值类型

  • 案例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    /*抽象类作为返回值类型*/
    abstract class Animal {
    public abstract void eat() ;
    }

    // 定义一个子类
    class Cat extends Animal {
    public void eat(){
    System.out.println("吃..........................") ;
    }
    }

    // 定义一个类
    class AnimalDemo {
    public static Animal getAnimal() {
    // Animal a = new Cat() ;
    // return a;
    return new Cat() ;
    }
    }

    // 测试类
    class ReturnDemo2 {
    public static void main(String[] args) {
    // 调用AnimalDemo的getAnimal这个方法
    Animal a = AnimalDemo.getAnimal() ;
    // 调用方法
    a.eat() ;
    }
    }

面向对象之接口名作为返回值类型

  • 案例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    /*接口作为返回值类型*/
    interface Jump {
    public abstract void jump() ;
    }

    // 定义一个子类
    class JumpImpl implements Jump {
    public void jump(){
    System.out.println("jum....................") ;
    }
    }

    // 定义一个类
    class JumpDemo {
    public static Jump getJump() {
    return new JumpImpl() ;
    }
    }

    // 测试类
    class ReturnDemo3 {
    public static void main(String[] args) {
    // 调用getJump方法
    Jump jump = JumpDemo.getJump() ;
    // 调用
    jump.jump() ;
    }
    }
-------------本文结束,感谢您的阅读-------------
您的支持将鼓励我继续创作!!