Java面向对象系列六(抽象类)



文章目录

  • Java面向对象系列六(抽象类)
  • 前言
  • 一、抽象类
  • 二、继承抽象类
  • 三、抽象方法
  • 总结



前言

抽象类的概念:
(1)在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
(2)抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
(3)在 Java 中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。


一、抽象类

在Java中用abstract class 来定义抽象类。如下实例:

/* 文件名 : 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");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public double computePay()
   {
     System.out.println("Inside 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类并没有什么不同,尽管是抽象类,但是仍然有3个成员变量,7个成员方法,一个构造方法。

下面我们再看一个例子:

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--");
      e.mailCheck();
   }
}

当你尝试编译 AbstractDemo 类时,会产生如下错误:

Employee.java:46: Employee is abstract; cannot be instantiated
Employee e = new Employee(“George W.”, “Houston, TX”, 43);
^
1 error


二、继承抽象类

我们可以通过以下方式继承Employee的属性:

/* 文件名 : Salary.java */
public class Salary extends Employee
{
   private double salary; //Annual salary
   public Salary(String name, String address, int number, double
      salary)
   {
       super(name, address, number);
       setSalary(salary);
   }
   public void mailCheck()
   {
       System.out.println("Within mailCheck of Salary class ");
       System.out.println("Mailing check to " + getName()
       + " with salary " + salary);
   }
   public double getSalary()
   {
       return salary;
   }
   public void setSalary(double newSalary)
   {
       if(newSalary >= 0.0)
       {
          salary = newSalary;
       }
   }
   public double computePay()
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}

尽管我们不能实例化一个 Employee 类的对象,但是如果我们实例化一个 Salary 类对象,该对象将从 Employee 类继承 7 个成员方法,且通过该方法可以设置或获取三个成员变量。

/* 文件名 : 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("Call mailCheck using Salary reference --");
      s.mailCheck();
 
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
    }
}

运行结果:

Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference –
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0
Call mailCheck using Employee reference–
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400


三、抽象方法

如果你想实现这样一个类,此类包含一个特别的成员方法,该方法具体实现由子类确定,那么可在父类中声明该方法为抽象函数。

代码如下(示例):

public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();
   
   //其余代码
}

注意事项:
(1)如果一个类包含抽象方法,则该类一定为抽象类。
(2)任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

继承抽象方法的子类必须重写抽象方法,否则,该子类必须声明为抽象类。最终,必须由该子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。


总结

  • 抽象类不能被实例化,如果被实例化,会编译报错。只有抽象类的非抽象子类可以实例化。
  • 抽象类中不一定包含抽象方法,有抽象方法的一定是抽象类。
  • 抽象类中的抽象方法只是声明。
  • 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
  • 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。