Java中的抽象


以下內容引用自http://wiki.jikexueyuan.com/project/java/abstraction.html

Abstraction是指在OOP中讓一個類抽象的能力。一個抽象類是不能被實例化的。類的功能仍然存在,它的字段,方法和構造函數都以相同的方式進行訪問。只是不能創建一個抽象類的實例。

如果一個類是抽象的,即不能被實例化,這個類如果不是子類它將沒有什么作用。這體現了在設計過程中抽象類是如何被提出的。一個父類包含子類的基本功能集合,但是父類是抽象的,不能自己去使用功能。

一、抽象類

使用關鍵字abstract來聲明一個抽象類。它出現在關鍵字class的前面。

/* File name : 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類沒什么不同。類現在是抽象的,但它仍然有三個字段,七個方法,一個構造函數。

現在如果嘗試以下代碼:

/* File name : AbstractDemo.java */
public class AbstractDemo
{
   public static void main(String [] args)
   {
      /* Following is not allowed and would raise error */
      Employee e = new Employee("George W.", "Houston, TX", 43);

      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
    }
}
//當進行編譯時,將得到下面的錯誤:
Employee.java:46: Employee is abstract; cannot be instantiated
      Employee e = new Employee("George W.", "Houston, TX", 43);
                   ^
1 error

二、繼承抽象類

可以如下繼承Employee類:

/* File name : 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對象,Salary對象將繼承Employee 的三個字段和七個方法。

/* File name : 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.

三、抽象方法

如果想一個提供特定方法的類,但是想要在他的子類中實際實現這個方法,可以在父類中聲明這個方法為抽象的。

abstract關鍵字也被用來定義抽象方法。一個抽象方法是有方法簽名的但沒有方法實體。

抽象方法無需定義,並且它的方法名以分號結束,不需要花括號。

public abstract class Employee
{
   private String name;
   private String address;
   private int number;

   public abstract double computePay();

   //Remainder of class definition
}

聲明一個抽象方法有兩個結果:

  • 如果一個類中含有一個抽象方法,類必須也是抽象的。
  • 任何一個子類必須覆蓋這個抽象方法,或者繼續將它聲明為抽象方法。

子類繼承一個抽象方法,必須要去覆蓋他。如果不這樣做的話,它們必須將其繼續聲明為抽象,或在它們的子類中去覆蓋它們。

最終,后代類不得不去實現抽象方法;否則會一直有一個不能被實例化的抽象類。

如果Salary繼承Employee類,則他必須如下要去實現computerPay()方法:

/* File name : Salary.java */
public class Salary extends Employee
{
   private double salary; // Annual salary

   public double computePay()
   {
      System.out.println("Computing salary pay for ");
      return salary/52;
   }

   //Remainder of class definition
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM