Java学习21--abstract抽象类

abstract抽象类

在Java中,abstract 是一个关键字,用于定义抽象类abstract class或抽象方法abstract method。abstract class是一种特殊的class,它不能用来建立具体的object,即不能实例化对象。abstract class通常用作其他类的基类,这些child class会提供abstract class中声明的abstract method的具体实现。

换言之,abstract抽象类就是搭建大框架用的,各个method具体怎么执行可以不管。先把大结构弄出来再说。

例如 abstract 一个人{
abstract 脑袋method{具体怎么构造脑袋method,让别人去写吧};
abstract躯干method{具体怎么完成躯干method,让别人去写吧};
abstract四肢method{具体怎么完成四肢method,让别人去写吧};
👋手method{非abstract的一般method 手👋method具体实现如下: XX个骨头神经元这样连接...};
abstract脚method{具体怎么完成脚method,让别人去写吧};

}

以下是关于Java abstract class的几个关键点:

  • abstract method:abstract class中可以包含abstract method(使用 abstract 关键字定义的method),也可以包含non-abstract method(即具有方法体的method)。
  • abstract method没有方法体,只有方法签名。child class必须提供abstract method的实现,除非child class本身也是abstract class(那就等待extends它的grandchild class来完成实现这些method)。

public abstract class AbstractClass {  

    public abstract void abstractMethod(); // 抽象方法  

  

    public void nonAbstractMethod() {  

        // 非抽象方法的具体实现 

    }  

}
  • abstract class 实例化:由于abstract method不能实例化(不能建立新的object对象),因此你不能使用 new 关键字来创建abstract class类型的object。abstract class只能作为其他class的基class使用。

AbstractClass obj = new AbstractClass(); // 错误,不能实例化抽象类
  • 继承抽象类:任何child class 都可以继承一个abstract class,除非这个child class是final的,那么它需要将abstract method的全部未尽method完成具体实现。因为任何final定义的class就不会再有子类了。如果继承abstract class的child class不是abstract标记的,那么它也必须提供abstract class中所有abstract method的实现。

public class SubClass extends AbstractClass {  

    @Override  

    public void abstractMethod() {  

        // 提供抽象方法的实现  

    }  

}

抽象类中的字段:抽象类可以包含字段(就是那些成员变量),这些字段可以是object的字段或static字段。子类可以直接访问这些字段,就像它们访问普通类的字段一样。比如下面的name和age,本身是不在cat和dog class中的,这两个字段都是从他们的父类animal abstract class中继承的。

假设有一些猫猫狗狗的class,他们有一个抽象类animal class作为父类,其中定义了一些动物共有的属性,如name和age,以及一些共有的行为,如eat()和sleep()。在主程序利用dog class和cat class新建一些cat和dog的objects,利用这些object去调用他们的父类animal class,并观察输出。

主程序如下:

package test;


public class testjan05{

        public static void main(String[] args) {
            Dog d1 = new Dog("doddy", 1);
            //新建一个object d1取Dog类
            Cat c1 = new Cat("catty", 2);
            //新建一个object c1取Cat类


            d1.displayInfo();
            // 执行dog class内部的displayInfo method
            // 执行过程中发现dog class内部并不存在displayInfo method,
            // 但是dog class的父类animal class存在名为displayInfo method
            //继承父类method 最终显示出狗狗的信息
            
            c1.displayInfo();
            // 和上面同理,执行cat class父类animal class内部的displayInfo method:显示猫咪的信息

            d1.eat(); // 查找dog class和其父类animal class有否存在eat method,发现父类是一个abstract eat method空心弹,所以在子类dog class重写override了这个eat method最后得到 狗狗吃饭
            c1.eat(); // 查找cat class和其父类animal class有否存在eat method,发现父类是一个abstract eat method空心弹,所以在子类cat class重写override了这个eat method最后得到 猫咪吃饭

            d1.sleep(); //执行dog class父类animal class的sleep method 狗狗睡觉
            c1.sleep(); //执行cat class父类animal class的sleep method 猫咪睡觉
        }

}




Dog class

package test;

public class Dog extends animal {
    public Dog(String ddname, int ddage) {
        super(ddname, ddage);
        // 去调用父类animal的constructor名字是animal,
        // 并继承了父类constractor的结构,p_name和p_age,
        // 于是在本级给了两个输入值ddname和ddage
    }

    @Override
    public void eat() {
        System.out.println("The dog eats dog food.");
    }
}

Cat Class


package test;

public class Cat extends animal {
    public Cat(String ccname, int ccage) {
        super(ccname, ccage); // 调用父类的构造方法
    }

    @Override
    public void eat() {
        System.out.println("The cat eats cat food.");
    }
}

猫狗class 的父类 animal class如下,注意animal class是一个抽象类

package test;

public abstract class animal {
    // 抽象类中的字段
    private String p_name;
    protected int p_age;

    // constructor method 构造方法,
    // 用于初始化class的各种字段
    public animal(String an_name, int an_age) {
        this.p_name = an_name; //以外来输入的an_name值对上面的private p_name进行了更新
        this.p_age = an_age; //以an_age的值对上面的protected p_age进行了更新
    }

    // abstruct method 抽象方法
    public abstract void eat();

    // general method 有具体执行的方法
    public void sleep() {
        System.out.println(p_name + " is sleeping.");
    }

    // 一个具体方法,用于显示动物的信息
    public void displayInfo() {
        System.out.println("Name: " + p_name);
        System.out.println("Age: " + p_age);
    }
}

显示输出

Name: doddy
Age: 1
Name: catty
Age: 2
The dog eats dog food.
The cat eats cat food.
doddy is sleeping.
catty is sleeping.

抽象类与接口:虽然抽象类abstract和接口interface都不能用来创建具体object,并且都可以定义abstract method,但它们之间有一些重要的区别。abstract抽象类可以包含字段(也就是定义的那些变量)和method的具体执行步骤,而接口interface不能写那些乱七八糟的。此外,一个class可以实现多个接口,但一个子class只能extends一个abstract class(Java不支持多重继承)。

Abstract Class特点总结:

子类需要extends abstract class抽象类,所以只能单方向单继承(接口可以多继承)
abstract class不能用来new object,其内部想做的method要么自己实现,要么靠子类去实现
abstract class里面可以写普通的method并且自己就完成其具体的执行方法
abstract method必须写在abstract class中

抽象类的用途:抽象类通常用于定义一种行为模式,让子类来遵循这种模式。通过抽象类,你可以定义一些通用的属性和方法,并在需要时让子类来提供特定的实现。使用抽象类可以实现代码的重用和模块化,同时保持代码的灵活性和可扩展性。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值