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