java面向对象四大核心特征之抽象---超详细(保姆级)

今天和大家聊聊抽象类这个概念,抽象类的出现实际上就是为了实现一种规则,比如:课堂上老师抛出一个问题,一个班的学生就针对这一个问题分成许多小组来讨论如何解决此问题,经过同学们的激烈讨论,得出许多解决此问题的方式,说白了就是老师指定了一种规约,约束学生们只能在此规约下完成问题的解答。迁移到抽象类中就是抽象类指定规约,子类继承抽象类具体实现规约内的方法实现。

抽象类

如果一个类中不具体化的描述一个对象,只是为了声明一个对象,并强制并要求其子类必须按照这个声明的约束来实现具体功能,来保证代码的规范性和一致性,这就是抽象类的意义。

我们来看下抽象类的定义:

csharp 复制代码
public abstract class Animal {
    protected String name;
    public int age;
    public Animal() {//无参构造
        
    }
    public Animal(String name, int age) {//有参构造
        this.name = name;
        this.age = age;
    }
    public void play() {
        System.out.println("Animal play method");
    }
}

测试代码:

typescript 复制代码
public class StartDemo1 {
    public static void main(String[] args) {
       Animal a = new Animal();
       a.play();
    }
}

运行一下测试代码看下效果:

​编辑

我们看到Animal 前使用了abstract关键字的修饰,实现了Animal 类的抽象化处理,当我们对Animal 类实例化时调用其内部方法报错了,说明抽象后的Animal是无法实例化的。

接下来我们让子类Cat继承父类Animal:

scala 复制代码
public class Cat extends Animal{
    private String name;
    private int sex;

    public Cat() {
        super();  // 调用父类的无参构造方法
    }

    public Cat(String name, int age, int sex) {
        super(name, age);  // 调用父类的有参构造方法
        this.sex = sex;
    }

}

测试代码如下:

typescript 复制代码
public class StartDemo1 {
    public static void main(String[] args) {
       Animal a = new Cat();
       a.play();
    }
}

运行一下测试代码:

​编辑

从执行结果我们可以看出子类继承父类后,如果子类对父类方法没有特殊需要个性化实现的功能,那么对父类方法可直接访问,抽象类最主要的特征就是必须让子类继承,不被继承不能实例化对象。

抽象方法

抽象方法就是没有方法体的方法,也就是没有方法实现内容,只有方法的声明,而且抽象方法必须存在于抽象类中。

带有抽象方法的抽象类:

csharp 复制代码
public abstract class Animal {
    protected String name;
    public int age;
    public Animal() {//无参构造
        this.name = "one";
        this.age = 0;
    }
    public Animal(String name, int age) {//有参构造
        this.name = name;
        this.age = age;
    }
    public abstract void play();//抽象方法
}

继承AnimalDog类:

scala 复制代码
public class Dog extends Animal{
    private String name;
    private int sex;
    public Dog() {
        super();  // 调用父类的无参构造方法
    }

    public Dog(String name, int age, int sex) {
        super(name, age);  // 调用父类的有参构造方法
        this.sex = sex;
    }
}

测试代码:

scala 复制代码
public class Dog extends Animal{
    private String name;
    private int sex;
    public Dog() {
        super();  // 调用父类的无参构造方法
    }

    public Dog(String name, int age, int sex) {
        super(name, age);  // 调用父类的有参构造方法
        this.sex = sex;
    }
}

运行测试代码效果如下:

​编辑

上边的测试代码居然报错了,大家可以看出如果是抽象类中声明了抽象方法,那么子类要么也是抽象类不用重写父类抽象方法,如果子类不是抽象类所有继承该抽象类的子类,必须要重写父类的抽象方法,这就是一种规约。

子类重写父类抽象方法后:

java 复制代码
public class Dog extends Animal{
    private String name;
    private int sex;
    public Dog() {
        super();  // 调用父类的无参构造方法
    }

    public Dog(String name, int age, int sex) {
        super(name, age);  // 调用父类的有参构造方法
        this.sex = sex;
    }
    @Override
    public void play() {
        System.out.println("Dog play method");
    }
}

测试结果:

​编辑

面向抽象编程:

面向抽象编程就是父类不需要关注子类对父类的具体实现,而父类能够通过子类继承关系将父类的引用指向子类对象,每个子类对象的功能实现都由父类类型统一调用。

比如Animal 的引用指向了CatDog

java 复制代码
public class StartDemo1 {
    public static void main(String[] args) {
        Animal c =new Cat();
        Animal d = new Dog();
        d.play();
        c.play();
    }

}

运行一下测试代码:

​编辑

我们看到父类引用分别指向了两个不同的子类对象上,那么父类以后每扩展一个子类,只要能够将引用指向子类,就能调用不同的子类方法和属性,这就确保所有子类都拥有一致的方法结构,建立一种可靠契约,实现将公共代码和逻辑放在抽象类的父类中,也能体现抽象和具体之间的关系,设计感清晰。

这种抽象编程模式,对我们在软件开发前先设计好框架,再去丰富软件内容提供了清晰的思路。

最后谢谢大家阅读,如果喜欢,请关注或点赞,我会持续将好的知识分享给大家。

相关推荐
Aurora_NeAr4 小时前
对比Java学习Go——程序结构与变量
后端
PEI044 小时前
MVCC(多版本并发控制)
java·开发语言·数据库
AntBlack4 小时前
每周学点 AI:ComfyUI + Modal 的一键部署脚本
人工智能·后端·aigc
半夏陌离5 小时前
SQL 实战指南:电商订单数据分析(订单 / 用户 / 商品表关联 + 统计需求)
java·大数据·前端
5大大大大雄5 小时前
docker容器日志处理
后端
我真的是大笨蛋5 小时前
K8S-Pod(上)
java·云原生·容器·kubernetes
我是哪吒5 小时前
分布式微服务系统架构第170集:Kafka消费者并发-多节点消费-可扩展性
后端·面试·github
纪元A梦6 小时前
贪心算法应用:数字孪生同步问题详解
java·算法·贪心算法