首页 > Java > java教程 > 正文

Java 中的接口和抽象类

Mary-Kate Olsen
发布: 2024-11-01 02:26:28
原创
900 人浏览过

接口和抽象类是实现抽象和多态性的基本组件。

什么是接口?

Java中的接口是一种引用类型,类似于类,只能包含抽象方法、静态方法、默认方法和静态最终变量(常量)。 Java 中接口用于实现抽象和多重继承。接口不能直接实例化。

Interfaces and Abstract Classes in Java

?在 Java 8 之前,接口只能有 抽象方法
这些方法的实现必须在单独的类中提供。因此,如果要在接口中添加新方法,则必须在实现相同接口的类中提供其实现代码。

为了解决这个问题,Java 8引入了默认方法的概念,它允许接口拥有带有实现的方法,而不影响实现该接口的类.

如果需要,可以通过实现类来覆盖默认方法。

接口的主要特性

  • 抽象方法:没有主体的方法,使用abstract关键字声明。
  • 默认方法:具有主体的方法,在 Java 8 中引入,允许接口提供默认实现。
  • 静态方法:属于接口本身的方法,不属于接口实例。
  • 常量:声明为静态和最终的变量,它们是隐式公共的。

什么是抽象类?

Java中的抽象类是不能自行实例化的类,可以包含抽象方法(没有主体的方法)和具体方法(有主体的方法)。抽象类用于为子类提供公共基础,允许代码重用和共享行为的定义。

抽象类的主要特征

  • 抽象方法:没有主体的方法,使用abstract关键字声明。
  • 具体方法:带有主体的方法,提供默认实现。
  • 构造函数:抽象类可以有构造函数,但不能直接实例化。
  • 实例变量:抽象类可以有实例变量和静态变量。

接口和抽象类之间的区别

多重继承

  • 接口:Java通过接口支持多重继承,允许一个类实现多个接口。
  • 抽象类:Java不支持类的多重继承,即一个类只能扩展一个抽象类。

方法体

  • 接口:在 Java 8 之前,接口不能包含方法体。在 Java 8 中,默认方法和静态方法可以有主体。
  • 抽象类:抽象类可以包含抽象方法(不带主体)和具体方法(带主体)。

变量

  • 接口:接口中的变量隐式是公共的、静态的和最终的。
  • 抽象类:抽象类可以有实例变量、静态变量和常量。

用法

  • 接口:非常适合定义多个类可以实现的契约。
  • 抽象类:适合为一系列相关类提供公共基础,共享代码和行为。

Java 的继承方法

Java只支持单继承,即每个类只能继承一个类的字段和方法。如果您需要从多个源继承属性,Java 提供了接口的概念,它是多重继承的一种形式。

?接口与类类似。但是,它们仅定义方法的签名,而不定义其实现。接口中声明的方法在类中实现。 多重继承当一个类实现多个接口时就会发生。

在Java中,多重继承是通过接口而不是类来实现的。这允许一个类实现多个接口,并从每个接口继承方法签名。下面是一个使用接口演示多重继承的示例。

使用接口的多重继承示例

让我们定义两个接口,Flyable 和 Swimmable,以及一个实现这两个接口的 Duck 类。

接口:可飞行

public interface Flyable {
    void fly();
}
登录后复制
登录后复制
登录后复制
登录后复制

接口:可游泳

public interface Swimmable {
    void swim();
}
登录后复制
登录后复制

类别: 鸭类

public class Duck implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("Duck is flying");
    }

    @Override
    public void swim() {
        System.out.println("Duck is swimming");
    }

    public static void main(String[] args) {
        Duck duck = new Duck();
        duck.fly();
        duck.swim();
    }
}
登录后复制
登录后复制

解释

  1. 接口

    • Flyable接口定义了一个方法fly()。
    • Swimmable接口定义了一个方法swim()。
  2. 班级:

    • Duck 类实现了 Flyable 和 Swimmable 接口。
    • Duck 类提供了 Fly() 和 Swim() 方法的实现。
  3. 主要方法:

    • 创建了一个 Duck 实例。
    • fly() 和 Swim() 方法在 Duck 实例上调用,表明 Duck 类继承了这两个接口的行为。

输出

Duck is flying
Duck is swimming
登录后复制
登录后复制

这里用一个简单的图来说明这种关系:

+----------------+
|    Flyable     |<--------------->Interface
|----------------|
| + fly()        |
+----------------+
          ^
          |
          | Implements
          |
+----------------+
|     Duck       |<--------------->Class
|----------------|
| + fly()        |
| + swim()       |
+----------------+
          ^
          |
          | Implements
          |
+----------------+
|   Swimmable    |<--------------->Interface
|----------------|
| + swim()       |
+----------------+
登录后复制
登录后复制

在此示例中,Duck 类通过实现 Flyable 和 Swimmable 接口来演示多重继承。这允许 Duck 类继承并提供两个接口中定义的方法的实现,展示了 Java 如何通过接口实现多重继承。


Java中的抽象类

Java 中的抽象类用于为一系列相关类提供公共基础。它们可以包含抽象方法(没有主体的方法)和具体方法(有主体的方法)。下面是一个演示抽象类使用的示例。

抽象类的示例

让我们定义一个抽象类 Animal 和两个扩展 Animal 类的子类 Dog 和 Cat。

抽象类:动物

public abstract class Animal {
    // Abstract method (does not have a body)
    public abstract void makeSound();

    // Concrete method (has a body)
    public void sleep() {
        System.out.println("The animal is sleeping");
    }
}
登录后复制

子类:狗

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog says: Woof!");
    }

    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.makeSound();
        dog.sleep();
    }
}
登录后复制

子类:猫

public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat says: Meow!");
    }

    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.makeSound();
        cat.sleep();
    }
}
登录后复制

解释

  1. 抽象类:动物

    • Animal 类被声明为抽象类,这意味着它不能直接实例化。
    • 它包含一个抽象方法 makeSound(),该方法必须由任何子类实现。
    • 它还包含一个具体的方法 sleep(),它提供了默认实现。
  2. 子类:狗

    • Dog 类扩展了 Animal 类。
    • 它提供了抽象方法 makeSound() 的实现。
    • main方法创建一个Dog实例并调用makeSound()和sleep()方法。
  3. 子类:猫

    • Cat 类扩展了 Animal 类。
    • 它提供了抽象方法 makeSound() 的实现。
    • main方法创建一个Cat实例并调用makeSound()和sleep()方法。

输出

对于狗类:

public interface Flyable {
    void fly();
}
登录后复制
登录后复制
登录后复制
登录后复制

对于猫类:

public interface Swimmable {
    void swim();
}
登录后复制
登录后复制

这里用一个简单的图来说明这种关系:

public class Duck implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("Duck is flying");
    }

    @Override
    public void swim() {
        System.out.println("Duck is swimming");
    }

    public static void main(String[] args) {
        Duck duck = new Duck();
        duck.fly();
        duck.swim();
    }
}
登录后复制
登录后复制

在此示例中,Animal 抽象类为 Dog 和 Cat 子类提供了公共基础。 Animal 类定义了一个必须由任何子类实现的抽象方法 makeSound() 和一个提供默认实现的具体方法 sleep()。 Dog 和 Cat 类扩展了 Animal 类并提供了它们自己的 makeSound() 方法的实现。

接口要点

  1. 抽象:Java中的接口是一种实现抽象的机制。
  2. 默认方法:默认情况下,接口方法是抽象且公共的。
  3. 方法类型:接口方法只能是 public、private、abstract、default、static 和 strictfp。
  4. 字段类型:接口字段(变量)只能是 public、static 或 Final。
  5. IS-A 关系:Java 接口也代表 IS-A 关系。
  6. 实例化:不能直接实例化,就像抽象类一样。
  7. 松耦合:可以用来实现松耦合。
  8. 隐式抽象:每个接口都是隐式抽象的。
  9. 默认方法:默认方法仅在接口中允许。
Duck is flying
Duck is swimming
登录后复制
登录后复制

实际应用

使用接口

接口通常用于定义 API、框架和库。例如,java.util.List接口提供了列表实现的契约,例如ArrayList和LinkedList。

+----------------+
|    Flyable     |<--------------->Interface
|----------------|
| + fly()        |
+----------------+
          ^
          |
          | Implements
          |
+----------------+
|     Duck       |<--------------->Class
|----------------|
| + fly()        |
| + swim()       |
+----------------+
          ^
          |
          | Implements
          |
+----------------+
|   Swimmable    |<--------------->Interface
|----------------|
| + swim()       |
+----------------+
登录后复制
登录后复制

使用抽象类

抽象类通常用于为一系列相关类提供基类。例如,java.util.AbstractList类提供了List接口的骨架实现,减少了子类需要实现的代码量。

public interface Flyable {
    void fly();
}
登录后复制
登录后复制
登录后复制
登录后复制

接口和抽象类之间的区别

SNo Interface Abstract Class
1 Interfaces cannot be instantiated Abstract classes cannot be instantiated
2 It can have both abstract and non-abstract methods It can have both abstract and non-abstract methods
3 In interfaces, all fields are automatically public, static, and final, and all methods that you declare or define (as default methods) are public In abstract classes, you can declare fields that are not static and final, and define public, protected, and private concrete methods
4 Interface supports multiple inheritance. Multiple interfaces can be implemented Abstract class or class can extend only one class
5 It is used if you expect that unrelated classes would implement your interface. Eg, the interfaces Comparable and Cloneable are implemented by many unrelated classes It is used if you want to share code among several closely related classes
6 It is used if you want to specify the behavior of a particular data type, but not concerned about who implements its behavior. It is used if you expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than public (such as protected and private)

参考:https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
当抽象类被子类化时,子类通常为其父类中的所有抽象方法提供实现。但是,如果没有,则子类也必须声明为抽象的。


专家意见

根据《Effective Java》的作者 Joshua Bloch 的说法,在定义类型时,接口比抽象类更受青睐,因为它们更灵活并且支持多重继承。然而,抽象类对于提供共享功能和减少代码重复很有用。

接口非常适合定义 mixins。相比之下,类非常适合定义具有内在属性的对象。

  • 约书亚·布洛赫

亮点

  • 接口:非常适合定义契约和支持多重继承。
  • 抽象类:适合为相关类提供公共基础,共享代码和行为。
  • 区别:接口只能有抽象方法(Java 8 之前),而抽象类可以同时有抽象方法和具体方法。
  • 用法:接口用于定义API和框架,而抽象类用于提供骨架实现。

进一步探索

在您自己的 Java 项目中探索接口和抽象类的强大功能。尝试使用接口定义合约并使用抽象类提供共享功能。与 Java 社区分享您的见解和经验,为集体知识和成长做出贡献。

欢迎对本文进行任何更正或补充。

public interface Flyable {
    void fly();
}
登录后复制
登录后复制
登录后复制
登录后复制

以上是Java 中的接口和抽象类的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板