Java - 抽象
根据词典定义,abstraction(抽象)是指处理思想而非事件的特性。例如,在电子邮件的情况下,用户无需了解发送电子邮件后发生的复杂细节,如电子邮件服务器使用的协议等,这些都被隐藏起来了。因此,要发送电子邮件,您只需输入内容、指定收件人地址,然后点击发送即可。
Java 抽象
抽象是将实现细节隐藏起来只向用户提供功能的过程。换言之,用户只需知道对象的功能是什么,而无需了解它是如何实现的。在 Java 编程中,抽象通过 Abstract classes(抽象类)和 interfaces(接口)来实现。
Java 抽象类
在 Java 中,如果一个类的声明中包含 abstract 关键字,则该类被称为抽象类。
Java 抽象类可以包含或不包含 abstract methods,即没有方法体的方法( public void get(); )
但是,如果一个类至少有一个 abstract method,则该类 必须 被声明为 abstract。
如果一个类被声明为 abstract,它不能被实例化。
要使用抽象类,必须从另一个类继承它,并为其中的 abstract methods 提供实现。
如果继承了一个抽象类,必须为其中所有的 abstract methods 提供实现。
示例:Java 抽象类
本节提供一个 Java 抽象类的示例。要在 Java 中创建抽象类,只需在类声明中 class 关键字前使用 abstract 关键字。
/* 文件名 : Employee.java */
/* 文件名:Employee.java */
public abstract class Employee {
private String name;
private String address;
private int number;
public Employee(String name, String address, int number) {
System.out.println("Constructing an Employee");
/* 构造一个 Employee */
this.name = name;
this.address = address;
this.number = number;
}
public double computePay() {
System.out.println("Inside Employee computePay");
/* 在 Employee computePay 内 */
return 0.0;
}
public void mailCheck() {
System.out.println("Mailing a check to " + this.name + " " + this.address);
/* 向此人寄送支票: */
}
public String toString() {
return name + " " + address + " " + number;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public void setAddress(String newAddress) {
address = newAddress;
}
public int getNumber() {
return number;
}
}
您可以观察到,除了 abstract methods 外,Employee 类与 Java 中的普通类相同。该类现在是 abstract 的,但它仍然有三个字段、七个方法和一个构造函数。
现在您可以尝试以下方式实例化 Employee 类 −
/* 文件名 : AbstractDemo.java */
/* 文件名:AbstractDemo.java */
public class AbstractDemo {
public static void main(String [] args) {
/* 以下操作不允许,会引发错误 */
Employee e = new Employee("George W.", "Houston, TX", 43);
System.out.println("\n Call mailCheck using Employee reference--");
/* 使用 Employee 引用调用 mailCheck -- */
e.mailCheck();
}
}
abstract class Employee {
private String name;
private String address;
private int number;
public Employee(String name, String address, int number) {
System.out.println("Constructing an Employee");
/* 构造一个 Employee */
this.name = name;
this.address = address;
this.number = number;
}
public double computePay() {
System.out.println("Inside Employee computePay");
/* 在 Employee computePay 内 */
return 0.0;
}
public void mailCheck() {
System.out.println("Mailing a check to " + this.name + " " + this.address);
/* 向此人寄送支票: */
}
public String toString() {
return name + " " + address + " " + number;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public void setAddress(String newAddress) {
address = newAddress;
}
public int getNumber() {
return number;
}
}
当您编译上述类时,会出现以下错误 −
Employee.java:46: Employee is abstract; cannot be instantiated
/* Employee 是抽象的;不能被实例化 */
Employee e = new Employee("George W.", "Houston, TX", 43);
^
1 error
继承 Java 抽象类
我们可以像继承具体类一样,以以下方式继承 Employee 类的属性 −
示例:在 Java 中继承抽象类
/* 文件名 : Salary.java */
public class Salary extends Employee {
private double salary; // 年薪
public Salary(String name, String address, int number, double salary) {
super(name, address, number);
setSalary(salary);
}
public void mailCheck() {
System.out.println("在 Salary 类的 mailCheck 中 ");
System.out.println("邮寄支票给 " + getName() + ",薪资 " + salary);
}
public double getSalary() {
return salary;
}
public void setSalary(double newSalary) {
if(newSalary >= 0.0) {
salary = newSalary;
}
}
public double computePay() {
System.out.println("为 " + getName() + " 计算薪资");
return salary/52;
}
}
在这里,你不能实例化 Employee 类,但你可以实例化 Salary 类,并通过这个实例访问 Employee 类的所有三个字段和七个方法,如下所示。
/* 文件名 : AbstractDemo.java */
public class AbstractDemo {
public static void main(String [] args) {
Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
System.out.println("使用 Salary 引用调用 mailCheck --");
s.mailCheck();
System.out.println("\n 使用 Employee 引用调用 mailCheck--");
e.mailCheck();
}
}
abstract class Employee {
private String name;
private String address;
private int number;
public Employee(String name, String address, int number) {
System.out.println("构造 Employee");
this.name = name;
this.address = address;
this.number = number;
}
public double computePay() {
System.out.println("在 Employee 的 computePay 中");
return 0.0;
}
public void mailCheck() {
System.out.println("邮寄支票给 " + this.name + " " + this.address);
}
public String toString() {
return name + " " + address + " " + number;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public void setAddress(String newAddress) {
address = newAddress;
}
public int getNumber() {
return number;
}
}
class Salary extends Employee {
private double salary; // 年薪
public Salary(String name, String address, int number, double salary) {
super(name, address, number);
setSalary(salary);
}
public void mailCheck() {
System.out.println("在 Salary 类的 mailCheck 中 ");
System.out.println("邮寄支票给 " + getName() + ",薪资 " + salary);
}
public double getSalary() {
return salary;
}
public void setSalary(double newSalary) {
if(newSalary >= 0.0) {
salary = newSalary;
}
}
public double computePay() {
System.out.println("为 " + getName() + " 计算薪资");
return salary/52;
}
}
输出
构造 Employee 构造 Employee 使用 Salary 引用调用 mailCheck -- 在 Salary 类的 mailCheck 中 邮寄支票给 Mohd Mohtashim,薪资 3600.0 使用 Employee 引用调用 mailCheck-- 在 Salary 类的 mailCheck 中 邮寄支票给 John Adams,薪资 2400.0
Java 抽象方法
如果您希望一个 class 包含特定 method,但希望该 method 的实际实现由子类决定,您可以在父类中将该 method 声明为 abstract。
abstract 关键字用于将 method 声明为 abstract。
您必须在 method 声明中 method 名称之前放置 abstract 关键字。
抽象 method 包含 method 签名,但没有 method 体。
抽象 method 在末尾使用分号 (;) 而不是大括号。
示例 1:Java 中的抽象方法实现
以下是抽象方法的示例。
public abstract class Employee {
private String name;
private String address;
private int number;
public abstract double computePay();
// 类的其余定义
}
将 method 声明为 abstract 有两个后果 −
包含它的 class 必须被声明为 abstract。
继承当前 class 的任何 class 必须要么重写抽象 method,要么将自身声明为 abstract。
注意 − 最终,后代 class 必须实现抽象 method;否则,您将得到一个无法实例化的抽象 class 层次结构。
假设 Salary class 继承 Employee class,那么它应该像下面这样实现 computePay() method −
/* 文件名 : Salary.java */
public class Salary extends Employee {
private double salary; // 年薪
public double computePay() {
System.out.println("Computing salary pay for " + getName());
return salary/52;
}
// 类的其余定义
}
示例 2:Java 中的抽象方法实现
以下示例展示了抽象方法的概念。
/* 文件名 : AbstractDemo.java */
public class AbstractDemo {
public static void main(String [] args) {
Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
System.out.println("salary: " + s.computePay());
}
}
abstract class Employee {
private String name;
private String address;
private int number;
public Employee(String name, String address, int number) {
System.out.println("Constructing an Employee");
this.name = name;
this.address = address;
this.number = number;
}
public abstract double computePay();
// 类的其余定义
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
class Salary extends Employee {
private double salary; // 年薪
public Salary(String name, String address, int number, double salary) {
super(name, address, number);
this.salary = salary;
}
public double computePay() {
System.out.println("Computing salary pay for " + getName());
return salary/52;
}
// 类的其余定义
}
输出
Constructing an Employee Computing salary pay for Mohd Mohtashim salary: 69.23076923076923