ポリモーフィズムとカプセル化

JavaBeginner
オンラインで実践に進む

はじめに

カプセル化とは、オブジェクトに関連する操作とデータをまとめて包むバッグのようなものです。ポリモーフィズムとは、オブジェクトが多くの形態をとることができる能力です。この実験では、それらがどのようなものか見ていきましょう。

ポリモーフィズム

ポリモーフィズムは、OOP の機能の 1 つで、異なる方法で単一のアクションを実行できるようにします。コンパイル時に解決される「ポリモーフィズム」は「静的ポリモーフィズム」または「コンパイル時ポリモーフィズム」(オーバーロードがこのタイプ)です。実行時に解決されるポリモーフィズムは「実行時ポリモーフィズム」と呼ばれます(オーバーライドがこのタイプ)。ポリモーフィズムはまた、オブジェクトが多くの形態をとることができる機能を提供します。OOP におけるポリモーフィズムの非常に一般的な使い方は、親クラスの参照を使って子クラスのオブジェクトを参照する場合です。複数の IS-A テストを通過できる任意の Java オブジェクトは、「ポリモーフィック」と見なされます。参照変数は、宣言された型のオブジェクトまたは宣言された型の任意のサブタイプのオブジェクトを参照できます。参照変数は、「クラス型」または「インターフェイス型」として宣言できます。継承の場合も、ポリモーフィズムの 1 つの形態です。なぜなら、さまざまな種類の動物の行動や特徴があるからです。しかし、ここではポリモーフィズムの別の形態を紹介します。

ポリモーフィズムのクラス図

/home/labex/project/polymorphismTest.javaファイルに次のコードを記述します。

// インターフェイス life を宣言します。いくつかのメソッドがありますが、ここでは省略します。
interface life{}
// ポリモーフィズムを実現するクラスを宣言します。内部の内容は、この場合には無視します。
class Animal{}
// Animal クラスと life インターフェイスを使う Human クラスを宣言します。
class Human extends Animal implements life{}

public class polymorphismTest{
    public static void main(String[] args){
        Human human = new Human();  // Human オブジェクトをインスタンス化する
        // Human は Animal、Object と直接または間接的な継承関係があります。
        // Human は life インターフェイスを実装しているので、instanceof 式は true を返します。
        System.out.println("human は Human のインスタンスですか? " + (human instanceof Human));
        System.out.println("human は Animal のインスタンスですか? " + (human instanceof Animal));
        System.out.println("human は life のインスタンスですか? " + (human instanceof life));
        System.out.println("human は Object のインスタンスですか? " + (human instanceof Object));
    }
}

出力

次のコマンドを使ってpolymorphismTest.javaファイルを実行します。

javac /home/labex/project/polymorphismTest.java
java polymorphismTest

出力を見てください。

humanはHumanのインスタンスですか? true
humanはAnimalのインスタンスですか? true
humanはlifeのインスタンスですか? true
humanはObjectのインスタンスですか? true

カプセル化

カプセル化は、プログラムの詳細を隠す概念です。他の呼び出し元は、プログラムがどのように機能するかを知ることなく、何を提供できるかだけを知る必要があります。カプセル化により、開発が簡略化されます。これは、データ(変数)とアルゴリズム(メソッドコード)をまとめるメカニズムです。カプセル化では、クラスの変数は他のクラスから隠され、クラスのメソッドを通じてのみアクセスできます。したがって、これは「データ隠蔽」とも呼ばれます。一般的に、クラスフィールドは private に宣言され、getter/setter メソッドを使ってデータにアクセスし制御します。public メソッドを定義するのは、他のクラスに機能を提供するため、または外部での使用のためだけです。時々、クラス内で特定の使用目的のためにのみ使用される private メソッドも定義します。これが、詳細を隠す方法です。

/home/labex/project/encapsulationTest.javaファイルに次のコードを記述します。

class Person{
    /*
     * Person には 2 つのメンバ変数があります。
     * それらは private なので、このクラスの外から直接アクセスできません。
    */
    private String name;
    private int age;
    // 空のコンストラクタ
    public Person(){

    }
    // 2 つのパラメータを持つコンストラクタ
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }
    // このメソッドを使って name の値を取得します。
    public String getName(){
        return this.name;
    }
    // このメソッドを使って name の値を設定します。
    public void setName(String name){
        this.name = name;
    }
    // このメソッドを使って age の値を取得します。
    public int getAge(){
        return this.age;
    }
    // このメソッドを使って age の値を設定します。
    public void setAge(int age){
        this.age = age;
    }
}
public class encapsulationTest{
    public static void main(String[] args){
        Person p = new Person();
        // setXXX() メソッドを使って人の名前と年齢を設定します。
        p.setName("Mike");
        p.setAge(20);
        // getXXX() メソッドを使って人の名前と年齢を取得します。
        System.out.println("Name: " + p.getName() + ", Age: " + p.getAge());
    }
}

出力

次のコマンドを使ってencapsulationTest.javaファイルを実行します。

javac /home/labex/project/encapsulationTest.java
java encapsulationTest

出力を見てください。

Name: Mike, Age: 20

まとめ

カプセル化により、object.XXX を使って直接オブジェクトのデータやプロパティにアクセスする必要はありません。代わりに、getXXX()setXXX() などの形式の標準メソッドを使ってその作業を行います。ジェネリックプログラミングでは、ポリモーフィズムの利点が明らかになりますが、今のところは、ポリモーフィズムがオブジェクトが多くの形態をとることを可能にすることを覚えておくだけです。