优秀的编程知识分享平台

网站首页 > 技术文章 正文

轻轻松松掌握抽象类与接口

nanyue 2025-01-12 17:33:58 技术文章 2 ℃

一:抽象类

  1. 什么是抽象类

抽象类,顾名思义,就是包含抽象方法的类。它用abstact关键字来修饰,是一种不能被实例话的类。简单来说,抽象类只能通过被继承来使用,不能直接创建一个对象。正因为如此,抽象类不能使用final修饰,因为final表示类不能被继承,而抽象类的存在意义就在于给其它的类继承。

/**
 * 动物抽象类: 1.abstract 修饰
 */
abstract class Animal{
}

public class Test {
    public static void main(String[] args) {
        //2.不能被实例化
        new Animal();
    }
}

/**
 * 狗继承动物抽象类:3.只能被子类继承extends
 */
class Dog extends Animal{
}
  1. 抽象类的特点
  • 包含抽象方法:抽象方法用abstact修饰的,没有具体实现内容。子类继承抽象类后,必须实现这些抽象方法。
  • 不能被实例化:抽象类不能直接创建对象,必须通过继承来使用。
  • 可以包含普通方法:抽象类不仅可以包含抽象方法,还可以包含普通方法。这样,你可以在抽象类定义一些通用的行为逻辑,子类可以选择继承这些逻辑。
  • 有构造方法:虽然抽象类不能为实例化,但它可以有构造方法,通常用于被子类调用,以初始化抽象类中的成员变量。
/**
 * 动物抽象类: 1.abstract 修饰
 */
abstract class Animal {

    //1.可以有成员变量
    private String name;

    //2.可以有构造方法通常用于被子类调用,以初始化抽象类中的成员变量。
    Animal(String name) {
        this.name = name;
    }

    //3.普通的方法
    void eat() {
        System.out.println(name + "吃饭");
    }

    //4.抽象方法
    abstract void move();
}
  1. 如何使用

当需要约束子类具有某些共同的行为,并且希望提供一些默认实现或者共享的状态时。

例如:动物有吃的行为,呼吸行为,移动行为。比如鸟,鱼,其中吃的行为这二个动物都是用嘴巴吃(普通方法);呼吸行为鸟是用鼻子,鱼是用鳃;移动行为鸟是脚(飞这里不讨论),鱼是用鳍来摆动。那这里的呼吸行为与移动行为,方式存在不同(抽象方法)。

代码演示:

/**
 * 动物抽象类: 
 */
abstract class Animal {
    private String name;

    //可以有构造方法通常用于被子类调用,以初始化抽象类中的成员变量。
    Animal(String name) {
        this.name = name;
    }

    //1.吃的行为(普通方法)
    void eat() {
        System.out.println(name + "吃");
    }

    //2.呼吸行为(抽象方法)
    abstract void breathe();

    //3.移动行为(抽象方法)
    abstract void move();
}

/**
 * 鸟 继承 动物抽象类
 */
class Bird extends Animal {

    //子类的成员变量
    private String birdName;

    Bird(String name) {
        super(name);
        this.birdName = name;
    }

    @Override
    void breathe() {
        System.out.println(birdName + "-使用嘴巴呼吸");
    }

    @Override
    void move() {
        System.out.println(birdName + "-使用脚移动");
    }
}

/**
 * 鱼 继承 动物抽象类
 */
class Fish extends Animal {
    //子类的成员变量
    private String fishName;

    Fish(String name) {
        super(name);
        this.fishName = name;
    }

    @Override
    void breathe() {
        System.out.println(fishName + "-使用鳃呼吸");
    }

    @Override
    void move() {
        System.out.println(fishName + "-使用鳍移动");
    }
}

public class Test {
    public static void main(String[] args) {
        Bird bird = new Bird("鸟");
        bird.eat();
        bird.breathe();
        bird.move();
        System.out.println("--------------------------");
        Fish fish = new Fish("鱼");
        fish.eat();
        fish.breathe();
        fish.move();
    }
}

运行结果:

鸟吃
鸟-使用嘴巴呼吸
鸟-使用脚移动
--------------------------
鱼吃
鱼-使用鳃呼吸
鱼-使用鳍移动

二:接口

  1. 什么是接口?

接口也是一种抽象类型,它的作用是定义一些抽象方法,通常以interface来声明。与抽象类不同的是,接口支持多继承,也就是说一个类可以实现多个接口,完美解决了Java单继承的限制问题。接口中的方法,默认情况下,都是public abstarct修饰的抽象方法。(Java8之后,接口可以定义default 方法和 staic方法,default方法可以有默认实现,子类可以选择是否重写)

  1. 接口的特点
  • 所有方法默认是public abstarct: 接口中的方法默认情况下不需要标明public abstarct,但实际上它们都是公开的抽象方法。子类实现接口时,必须提供这些方法的实现。
  • 没有构造方法:接口不能有构造方法,因为它不是类的一种,它是一种行为的定义,不涉及对象的构造。
  • 支持多实现:一个类可以实现多个接口,从而打破java单继承的局限性。
  • 接口中的成员只能是public static final的静态变量:接口中不能定义普通的成员变量,所有成员都是public static final修饰的静态变量。
  1. 如何使用

当遇到需要设计一些完全无关的类,它们之间并没有继承关系,但你希望它们实现相同的行为接口,那就可以使用接口了。

例如:

支付功能,有微信,支付宝,银行卡等,它们都有一个相同的行为支付,那我们可以设计一个接口。

代码演示:

/**
 * @Author 
 * @Description
 * @Date 
 */
public class PayTest {
    public static void main(String[] args) {
        WeiXin weiXin = new WeiXin();
        weiXin.payment();
        System.out.println("==================");
        ZhiFuBao zhiFuBao = new ZhiFuBao();
        zhiFuBao.payment();
        System.out.println("==================");
        YinHang yinHang = new YinHang();
        yinHang.payment();
    }
}


//支付接口
interface Pay{

    //相同的支付行为,支付方法
    void payment();
}

//微信实现类
class WeiXin implements Pay{

    @Override
    public void payment() {
        System.out.println("微信支付");
    }
}

//支付宝实现类
class ZhiFuBao implements Pay{

    @Override
    public void payment() {
        System.out.println("支付宝支付");
    }
}

//银行实现类
class YinHang implements Pay{

    @Override
    public void payment() {
        System.out.println("银行卡支付");
    }
}

抽象类和接口是 Java 中两个非常重要的概念,它们都用于定义类的行为规范,但是它们的使用场景和特性各不相同:

  • 抽象类 适合用于共享状态和行为逻辑的场景,通常用于子类之间存在紧密联系时。
  • 接口 适合用于为无关类提供统一的行为规范,特别是当你需要实现多个行为时,接口的多继承特性非常有用。
最近发表
标签列表