一、抽象类和抽象方法官方教程
博主其他介绍抽象类的文章:① Java 中的抽象类及其作用;② 接口、抽象类和匿名类
📖 【抽象类的作用】抽取子类的公共实现(或子类方法中的公共代码)到抽象父类中,要求子类必须要单独实现的方法(或代码块)定义成抽象方法。
🍀 上面对抽象类的作用的描述比较难理解,博主有半年之久的开发经验😊,觉得抽象类的作用相当巧妙且有用。【这也是博主为什么把抽象类的作用放在文章开头的原因】
🍀 文章后面会用具体代码体现抽象类的巧妙作用
✏️ An abstract class is a class that is declared abstract
—it may or may not include abstract methods
. Abstract classes cannot be instantiated, but they can be subclassed.
📜被abstract
关键字修饰的类就是抽象类,抽象类中可能包含抽象方法,也可能不包含抽象方法。抽象类不能被实例化,但可以被继承。
✏️ An abstract method is a method that is declared without an implementation (without braces, and followed by a semicolon)
📜 抽象方法被abstract
关键字修饰。抽象方法是没有具体实现的(没有花括号,末尾有分号)
✏️ If a class includes abstract methods
, then the class itself must be declared abstract.
📜 如果一个类中包含抽象方法,则该类本身必须也要被abstract
关键字修饰(则该类本身必须是抽象类)
📜 抽象方法不能定义在非抽象类中
/**
* Animal 是一个抽象类
* eat() 是一个抽象方法
*/
public abstract class Animal {
public abstract void eat();
}
✏️ When an abstract class
is subclassed, the subclass usually provides implementations for all of the abstract methods
in its parent class. However, if it does not, then the subclass must also be declared abstract.
📜 若一个抽象类被继承的话,该抽象类的子类需要实现它的父类(抽象类)中的所有抽象方法。但是,如果子类不想实现抽象父类中的抽象方法的话,子类也必须被声明为抽象类。
/**
* Animal 是一个抽象类
* eat() 是一个抽象方法
*/
public abstract class Animal {
public abstract void eat();
public abstract void test();
}
abstract class LittleDog extends Animal {
@Override
public void eat() {
System.out.println("Dog eats bones.");
}
}
class BigDog extends LittleDog {
@Override
public void test() {
System.out.println("BigDog test");
}
public static void main(String[] args) {
// Dog eats bones.
new BigDog().eat();
}
}
二、抽象类知识点罗列
从大方向来看, 抽象类在非抽象类的基础上多了一个功能,且少了一个功能:①【多】抽象类可以定义抽象方法;②【少】抽象类不能实例化
✏️ 抽象类不能被实例化
✏️ 抽象类中不一定要包含抽象方法
✏️ 一旦类中有抽象方法,则该类必须是抽象类
✏️ abstract
只能修饰类和方法
✏️ 抽象类中依然可以定义非抽象方法、构造器、静态属性、成员变量、初始化块等【抽象类在非抽象类的基础上多了可以定义抽象方法的功能】
🍀 抽象类不能被实例化,但它的构造器依然是必须的(抽象类的构造器是让子类来调用的)✏️ 抽象方法没有实现(没有花括号,花括号被分号替代了)
✏️ 如果一个类继承了抽象类,则该子类必须实现抽象父类中的所有抽象方法,除非该子类也是抽象类【当子类是抽象类的时候,子类可以实现抽象父类的部分抽象方法(其他抽象方法可由抽象子类的子类实现)】
✏️ final
(被 final 修饰的类不能被继承;被 final 修饰的方法不能被重写)和abstract
关键字不能组合使用使用【final 和 abstract 组合使用会产生矛盾】
🍀 抽象类需要被子类继承,进而让子类实现抽象类中的抽象方法。若用 final 修饰抽象类,则抽象类无法被继承,那么抽象类中的抽象方法将毫无意义。
🍀 抽象方法需要被子类重写,否则抽象方法会毫无意义。若用 final 修饰抽象方法,则表示该方法不能被重写。
✏️ abstract 不能和 private 组合使用在方法中(抽象方法私有了子类就无法实现了)【private 不能修饰顶级类】
✏️ abstract 不能和 static 组合使用
🍀 抽象方法不能用 private、final 和 static 来修饰(它们都是和重写相违背的)
三、抽象类的作用
📖 【抽象类的作用】抽取子类的公共实现(或子类方法中的公共代码)到抽象父类中,要求子类必须要单独实现的方法(或代码块)定义成抽象方法。
计算某段代码的执行时间
public class CodeTimes {
public static void main(String[] args) {
// 获取当前时间的毫秒值
long start = System.currentTimeMillis();
String s = "点赞";
for (int i = 0; i < 50000; i++) {
s += i; // 字符串的拼接操作是非常耗时的
}
long end = System.currentTimeMillis();
long duration = (end - start) / 1000;
// 花费【6】秒
System.out.println("\n花费【" + duration + "】秒");
}
}
🍀 上图红框中的代码不是一层不变(是不确定的),每次传入测试的代码是多种多样的。可创建一个抽象方法代替这段代码,具体抽象方法中的代码是啥:让子类实现(提供)
public abstract class CodeTimes {
public abstract void codeBlock();
public void check() {
long start = System.currentTimeMillis();
codeBlock();
long end = System.currentTimeMillis();
long duration = (end - start) / 1000;
// 花费【6】秒
System.out.println("\n花费【" + duration + "】秒");
}
}
class WhateverTest extends CodeTimes {
public static void main(String[] args) {
// 花费【7】秒
new WhateverTest().check();
}
/**
* 该方法中的代码会被传递到 CodeTimes 类的 check 方法的中
*/
@Override
public void codeBlock() {
String s = "点赞";
for (int i = 0; i < 55555; i++) {
s += i; // 字符串的拼接操作是非常耗时的
}
}
}
这个功能用【接口】实现会更加巧妙
抽象模板设计模式就是这种思想
结束, 如有错误请不吝赐教