1. ホーム
  2. Java

Java基礎編 - オブジェクト指向

2022-02-13 22:02:30

3つの主な機能

カプセル化

抽象的なデータ型を使用して、データとデータに基づく操作をカプセル化し、不可分の独立したエンティティを形成する。

データは抽象データ型の内部で保護され、内部の詳細は可能な限り隠蔽され、外部と接続するための一部の外部インタフェースのみが残されています。

ユーザーはオブジェクトの内部の詳細を知る必要はなく、オブジェクトが外部に提供するインターフェースを通じてアクセスすることができる。

メリット

  • カップリングの低減:開発、テスト、最適化、使用、理解、修正を独立して行うことができる
  • メンテナンス負荷の軽減:プログラマがより理解しやすく、他のモジュールに影響を与えることなくデバッグが可能です。
  • 効率的なパフォーマンスチューニング:プロファイリングにより、どのモジュールがシステムパフォーマンスに影響を及ぼしているかを特定することができます。
  • ソフトウェアの再利用性の向上
  • 大規模システム構築のリスクを軽減:システム全体が使用不能になっても、個々のモジュールは使用可能な場合がある

次のPersonクラスは、名前、性別、年齢のプロパティをカプセル化しています。Person オブジェクトの名前と性別のプロパティを取得する方法は get() メソッドのみで、age プロパティは work() メソッドで利用できます。

genderプロパティはintデータ型を使用して格納され、ユーザーがこの実装の詳細に気づかないようにカプセル化されていることに注意してください。そして、genderプロパティで使用されるデータ型を変更する必要がある場合、クライアント側のコードに影響を与えることなく変更することができます。

public class Person {

    private String name;
    private int gender;
    private int age;

    public String getName() {
        return name;
    }

    public String getGender() {
        return gender == 0 ? "man" : "woman";
    }

    public void work() {
        if (18 <= age && age <= 50) {
            System.out.println(name + " is working very hard!");
        } else {
            System.out.println(name + " can't work any more!");
        }
    }
}


継承

継承は  IS-A  例えば、Cat と Animal は IS-A の関係にあり、Cat は Animal を継承して Animal の非プライベートなプロパティやメソッドを取得することができる。

継承はリヒター置換の原則に従うべきであり、子オブジェクトはすべての親オブジェクトを置換できなければならない。

CatはAnimalとして使うことができます。つまり、Animalを使ってCatオブジェクトを参照することができるのです。親クラスが子オブジェクトを参照することを  上方遷移  .

Animal animal = new Cat();


ポリモルフィック

ポリモーフィズムは、コンパイル時ポリモーフィズムとランタイムポリモーフィズムに分けられます。

  • コンパイル時ポリモーフィズムとは、主にメソッドのオーバーロードを指します。
  • ランタイムポリモーフィズムとは、プログラム中で定義されたオブジェクト参照の具体的な型が実行時に決定されることを指す

ランタイム・ポリモーフィズムには3つの条件がある。

  • 継承
  • オーバーライド(書き換え)
  • 上方変換

次のコードでは、Instrumentクラスは2つのサブクラスを持っています。WindとPercussionの2つのサブクラスがあり、どちらも親クラスのplay()メソッドをオーバーライドし、main()メソッドでWindとPercussionオブジェクトを参照するために親クラスInstrumentを使用します。Instrumentの参照先でplay()メソッドを呼び出すと、Instrumentクラスのメソッドではなく、実際に参照したクラスのplay()メソッドが実行されます。

public class Instrument {
    public void play() {
        System.out.println("Instument is playing... ");
    }
}

public class Wind extends Instrument {
    public void play() {
        System.out.println("Wind is playing... ");
    }
}

public class Percussion extends Instrument {
    public void play() {
        System.out.println("Percussion is playing... ");
    }
}

public class Music {
    public static void main(String[] args) {
        List<Instrument> instruments = new ArrayList<>();
        instruments.add(new Wind());
        instruments.add(new Percussion());
        for(Instrument instrument : instruments) {
            instrument.play();
        }
    }
}


クラス図

以下のクラス図では  PlantUML(新規ウィンドウを開く) 詳しい構文や使い方は、http://plantuml.com/ を参照してください。

一般化

Javaでextendsキーワードを使用して、継承関係を記述するために使用します。

@startuml

title Generalization

class Vihical
class Car
class Trunck

Vihical <|-- Car
Vihical <|-- Trunck

@enduml


実現関係(Realization)

Javaでimplementキーワードを使用して、インターフェースを実装するために使用します。

@startuml

title Realization

interface MoveBehavior
class Fly
class Run

MoveBehavior <|... Fly
MoveBehavior <|. Run

@enduml


集計

は、全体が部分から構成されているが、全体と部分が強く依存していないことを示す。

@startuml

title Aggregation

class Computer
class Keyboard
class Mouse
class Screen

Computer o-- Keyboard
Computer o-- Mouse
Computer o-- Screen

@enduml



構成

集合と異なり、合成では全体と部分が強く依存し、全体が存在しなければ部分も存在しない。例えば、ある会社とある部署があったとして、その部署がなければ会社は存在しない。しかし、会社と社員は集合体であり、会社はなくなっても社員は存在するのだから、集合体である。

@startuml

title Composition

class Company
class DepartmentA
class DepartmentB

Company *-- DepartmentA
Company *-- DepartmentB

@enduml


協会

異なるクラスのオブジェクト間に関連があることを示す。これは、実行時プロセスの状態に依存しない静的な関係であり、最初の段階で決定することができる。そのため、1対1、多対1、多対多の関連付けとして表現することもできる。例えば、生徒と学校は連想関係である。学校は多くの生徒を持つことができるが、生徒は1つの学校にしか属さないので、多対一の関係であり、実行開始前に決定することができる。

@startuml

title Association

class School
class Student

School "1" - "n" Student

@enduml


依存性

アソシエーションと異なり、依存関係は実行時に機能する。クラスAとクラスBの間の依存関係には、主に3つの形式がある。

  • クラスAはクラスBの(あるメソッドの)ローカル変数である。
  • クラスAは、クラスBのメソッドのパラメータです。
  • クラス A はクラス B にメッセージを送信し、クラス B の変更に影響を与えます。

@startuml

title Dependency

class Vihicle {
    move(MoveBehavior)
}

interface MoveBehavior {
    move()
}

note "MoveBehavior.move()" as N

Vihicle ... > MoveBehavior

Vihicle ... N

@enduml


参考文献