03_Javaマルチステート

82648 ワード

Javaマルチステート
マルチステートは、同じ動作が複数の異なる表現形式または形態を有する能力である.
多態性は対象の多種の表現形式の体現である.
例えば、「ペット」という対象には、子猫、子犬、トカゲなど、さまざまな表現や実現があります.そこで私はペットショップに行って「ペットを1匹ください」と言って、ウェイターは私に子猫、子犬、トカゲをあげてもいいです.私たちは「ペット」という対象が多態性を持っていると言っています.
次に、Javaのマルチステートをインスタンスで理解します.
public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}

Deerクラスには多重継承があるため、多態性があります.以上の例は以下のように解析される.
ひとつのDeer IS-A(ひとつ)Animal ひとつのDeer IS-A(ひとつ)Vegetarian ひとつのDeer IS-A(ひとつ)Deer 一つのDeer IS-A(一つの)Object Javaでは、どのオブジェクトもIS-AテストのタイプとObjectクラスを通過できるため、すべてのオブジェクトに多態性があります.
オブジェクトにアクセスする唯一の方法は、参照型変数を使用することです.
参照型変数には1つのタイプしかありません.宣言されると、参照型変数のタイプは変更できません.
参照型変数は、finalとして宣言されていないことを前提として、他のオブジェクトにリセットできます.また、同じタイプまたは互換性のあるオブジェクトを参照することもできます.クラスタイプまたはインタフェースタイプとして宣言できます.
参照型変数をDeerオブジェクトの参照に適用する場合、次の宣言は正当です.
Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;

すべての参照型変数d,a,v,oはスタック内の同じDeerオブジェクトを指す.
ダミーメソッド
Javaでは,クラスを設計する際にリロードされるメソッドの挙動が多態性にどのように影響するかを紹介する.
メソッドのリロード,すなわちサブクラスが親クラスをリロードできる方法について議論した.
サブクラスオブジェクトがリロードメソッドを呼び出すと、親クラスでリロードされるメソッドではなく、サブクラスのメソッドが呼び出されます.
親クラスでリロードされるメソッドを呼び出すには、キーワードsuperを使用する必要があります.
/*     : Employee.java */
public 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 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クラスを継承するとします.
/*     : 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;
   }
}

次のコードをよく読んで、出力結果を出してみましょう.
/*     : VirtualDemo.java */
public class VirtualDemo
{
   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.0

例では、2つのSalaryオブジェクトをインスタンス化します.1つはSalaryリファレンスs、もう1つはEmployeeリファレンスを使用します.
コンパイル時、コンパイラはSalaryクラスのmailCheck()メソッドの宣言をチェックします.
s.mailCheck()を呼び出すと、Java仮想マシン(JVM)はSalaryクラスのmailCheck()メソッドを呼び出す.
eはEmployeeの参照であるため,eを呼び出すmailCheck()メソッドは全く異なる結果となる.
コンパイラがe.mailCheck()メソッドをチェックすると、コンパイラはEmployeeクラスのmailCheck()メソッドをチェックします.
コンパイルの際、コンパイラはEmployeeクラスのmailCheck()メソッドを使用して文を検証しますが、実行時にJava仮想マシン(JVM)がSalaryクラスのmailCheck()メソッドを呼び出します.
この動作を仮想メソッド呼び出しと呼び、このメソッドを仮想メソッドと呼ぶ.
Javaではすべてのメソッドがこのように表現され、コンパイル時にソースコードで変数がどのようなデータ型であるかにかかわらず、書き換えメソッドは実行時に呼び出されます.