04_Java抽象クラス

105365 ワード

Java抽象クラス
オブジェクト向けの概念では、すべてのオブジェクトがクラスによって描かれていますが、逆に、すべてのクラスがオブジェクトを描くために使われているわけではありません.1つのクラスに特定のオブジェクトを描くのに十分な情報が含まれていない場合、このようなクラスは抽象クラスです.
抽象クラスはオブジェクトをインスタンス化できないほか、クラスの他の機能は依然として存在し、メンバー変数、メンバーメソッド、構築メソッドのアクセス方法は通常のクラスと同じです.
抽象クラスはオブジェクトをインスタンス化できないため、抽象クラスは継承されなければ使用できません.そのため、抽象クラスを設計するかどうかを設計段階で決定することが多い.
親クラスには、子クラスの集合の一般的なメソッドが含まれていますが、親自体が抽象的であるため、これらのメソッドは使用できません.
抽象クラス
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つのメンバーメソッド、および1つの構築メソッドがあることに注意してください.次の例を試してみましょう.
/*     : AbstractDemo.java */
public class AbstractDemo
{
   public static void main(String [] args)
   {
      /*        ,      */
      Employee e = new Employee("George W.", "Houston, TX", 43);

      System.out.println("
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クラスから3つのメンバー変数と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("
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.

抽象メソッド
このようなクラスを設計したい場合は、そのサブクラスによって決定される特別なメンバーメソッドを含むクラスを設計します.親クラスで抽象メソッドとして宣言できます.
Abstraactキーワードは同様に抽象メソッドを宣言するために使用することができ、抽象メソッドにはメソッド名が1つしか含まれず、メソッドボディはありません.
抽象メソッドは定義されておらず、メソッド名の後ろにカッコではなくセミコロンが直接付いています.
public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();
   
   //    
}

抽象メソッドを宣言すると、次の2つの結果が得られます.
クラスに抽象メソッドが含まれている場合は、クラスは抽象クラスでなければなりません.
任意のサブクラスは、親クラスの抽象メソッドを書き換えるか、自身を抽象クラスと宣言する必要があります.
抽象メソッドを継承するサブクラスは、メソッドを再ロードする必要があります.そうでなければ、サブクラスも抽象クラスとして宣言する必要があります.最終的には、この抽象メソッドを実装するサブクラスが必要です.そうしないと、最初の親から最終的なサブクラスまでオブジェクトをインスタンス化するために使用できません.
SalaryクラスがEmployeeクラスを継承している場合は、computePay()メソッドを実装する必要があります.
/*     : Salary.java */
public class Salary extends Employee
{
   private double salary; // Annual salary
  
   public double computePay()
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }

   //    
}