JavaRush /Java Blog /Random-JA /OOP の原則

OOP の原則

Random-JA グループに公開済み
Java はオブジェクト指向言語です。これは、オブジェクト指向スタイルを使用して Java プログラムを作成する必要があることを意味します。このスタイルは、プログラム内でのオブジェクトとクラスの使用に基づいています。

OOP の基本原則:

OOP の原則 - 1例を参考に、クラスとオブジェクトとは何か、また、実際に OOP の基本原則 (抽象化、継承、ポリモーフィズム、カプセル化) を適用する方法を理解してみましょう。

オブジェクトとは何ですか?

私たちが住む世界は物体で構成されています。周りを見回すと、私たちは家、木、車、家具、食器、コンピューターに囲まれていることがわかります。これらのアイテムはすべてオブジェクトであり、それぞれに一連の特定の特性、動作、および目的があります。私たちはオブジェクトに慣れており、常にそれらを非常に特殊な目的に使用します。たとえば、仕事に行く必要がある場合は車を使い、食事をしたい場合は食器を使い、リラックスする必要がある場合は快適なソファが必要です。人は日常生活の問題を解決するために客観的に考えることに慣れています。これがプログラミングでオブジェクトを使用する理由の 1 つであり、プログラムを作成するこのアプローチはオブジェクト指向と呼ばれました。例を挙げてみましょう。新しい電話モデルを開発し、その量産を開始したいと考えていると想像してください。電話機の設計者は、電話機が何のためにあるのか、どのように機能するのか、どの部品で構成されているのか (ケース、マイク、スピーカー、ワイヤー、ボタンなど) を知っています。ただし、これらのパーツを接続する方法を知っているのはあなただけです。ただし、携帯電話を個人的に製造する予定はなく、そのために従業員全員がスタッフを抱えています。電話機の部品の接続方法を毎回説明する必要がなく、製造中のすべての電話機が同じに仕上がるように、製造を開始する前に、次の形式で図面を作成する必要があります。電話機の構造の説明。OOPでは、このような記述、描画、ダイアグラム、テンプレートをクラスと呼び、プログラムの実行時にクラスからオブジェクトが作成されます。 クラスとは、フィールド、メソッド、コンストラクターから構成される一般的なテンプレートのような、まだ作成されていないオブジェクトの記述であり、オブジェクトは、この記述に基づいて作成されたクラスのインスタンスです。

OOPの抽象化

ここで、電話を例として、現実世界のオブジェクトからプログラム内のオブジェクトにどのように移動できるかを考えてみましょう。この通信手段の歴史は 100 年を超え、現代の電話は 19 世紀の前身とは異なり、はるかに複雑な装置です。電話を使用するとき、私たちはその構造や内部で行われるプロセスについて考えません。電話機の開発者が提供する機能、つまりボタンやタッチスクリーンを使用して番号を選択し、電話をかけるだけです。最初の電話インターフェイスの 1 つは、電話をかけるために回すノブでした。もちろん、これはあまり便利ではありませんでした。それにもかかわらず、ハンドルは適切にその機能を果たしました。最新の電話機と最初の電話機を見れば、19 世紀後半のデバイスと最新のスマートフォンの両方にとって重要な最も重要な詳細がすぐにわかります。これは、電話をかける(番号をダイヤルする)ことと電話を受けることです。本質的に、これが電話を電話たらしめる理由であり、他のものではありません。ここで、オブジェクトに関する最も重要な特性と情報を強調表示するという原則を OOP に適用しました。OOP のこの原理は抽象化と呼ばれます。 OOP における抽象化は、現実世界の問題の要素をプログラム内のオブジェクトとして表現する方法としても定義できます。抽象化は常に、オブジェクトまたはオブジェクトのプロパティに関する情報の一般化に関連しているため、主なことは、解決されている問題のコンテキストにおいて重要な情報を重要でない情報から分離することです。この場合、複数のレベルの抽象化が存在する可能性があります。抽象化の原理を携帯電話に適用してみましょう。まず、最初から現在に至るまでの最も一般的なタイプの電話を紹介します。たとえば、それらは図 1 に示す図の形式で表すことができます OOP の原則 - 2。 ここで、抽象化を利用して、このオブジェクト階層内の一般的な情報を強調表示できます。オブジェクトの一般的な抽象タイプである電話、オブジェクトの一般的な特性です。電話機 - その誕生の年、そして共通のインターフェース - すべての電話機は通話の送受信が可能です。Java では次のようになります。
public abstract class AbstractPhone {
    private int year;

    public AbstractPhone(int year) {
        this.year = year;
    }
    public abstract void call(int outputNumber);
    public abstract void ring (int inputNumber);
}
この抽象クラスに基づいて、他の基本的な Java OOP 原則を使用してプログラム内で新しいタイプの電話機を作成できます。これについては以下で検討します。

カプセル化

抽象化の助けを借りて、すべてのオブジェクトに共通するものを強調します。ただし、各電話モデルは個別であり、他のモデルとは多少異なります。プログラムに境界線を引き、この個性を指定するにはどうすればよいでしょうか? ユーザーが誤ってまたは故意に携帯電話を壊したり、あるモデルを別のモデルに変換しようとしたりしないようにするにはどうすればよいでしょうか? 現実のオブジェクトの世界では、答えは明白です。すべての部品を電話本体に組み込む必要があります。結局のところ、これを行わずに、電話機の内部と電話機を接続するワイヤーをすべて外部に残しておくと、電話機の動作を「改善」したいと考える好奇心旺盛な実験者が間違いなく現れるでしょう。オブジェクトの設計と操作におけるこのような干渉を避けるために、OOP はカプセル化の原理を使用します。これは、オブジェクトの属性と動作が 1 つのクラスに結合され、オブジェクトの内部実装が隠蔽される OOP のもう 1 つの基本原理です。ユーザーとオブジェクトを操作するためのオープン インターフェイスが提供されます。プログラマの仕事は、どの属性とメソッドをパブリックにアクセスできるか、またどの属性とメソッドがオブジェクトの内部実装であり変更すべきではないかを判断することです。

カプセル化とアクセス制御

製造中に、電話機の背面に、製造年や製造会社のロゴなどの情報が刻印されているとします。この情報は、このモデル、つまりその状態を非常に具体的に特徴づけます。携帯電話の開発者はこの情報の不変性を考慮したと言えます。彫刻を削除しようと考える人は誰もいないでしょう。Java の世界では、将来のオブジェクトの状態はフィールドを使用してクラスで記述され、その動作はメソッドを使用して記述されます。状態と動作を変更する機能は、フィールドとメソッドへのアクセス修飾子 ( privateprotectedpublic、およびdefault(デフォルトのアクセス)) を使用して実行されます。たとえば、作成年、電話メーカーの名前、およびメソッドの 1 つはクラスの内部実装に属し、プログラム内の他のオブジェクトによって変更できないと判断しました。コードを使用すると、クラスは次のように記述できます。
public class SomePhone {

    private int year;
    private String company;
    public SomePhone(int year, String company) {
        this.year = year;
        this.company = company;
    }
private void openConnection(){
    //findComutator
    //openNewConnection...
}
public void call() {
    openConnection();
    System.out.println("I'm calling a number");
}

public void ring() {
    System.out.println("Дзынь-дзынь");
}

 }
修飾子は、privateクラスのフィールドとメソッドをそのクラス内でのみ使用できるようにします。これは、private外部からフィールドにアクセスできず、privateメソッドを呼び出すこともできないことを意味します。メソッドへのアクセスを非表示openConnectionにすると、このメソッドの内部実装を自由に変更できるようになります。これは、このメソッドが他のオブジェクトによって使用されず、その操作が中断されないことが保証されているためです。オブジェクトを操作するには、修飾子をcall使用してメソッドを開いたままにします。オブジェクトへのアクセスが完全に拒否されるとオブジェクトは役に立たなくなるため、オブジェクトを操作するためのパブリック メソッドの提供もカプセル化メカニズムの一部です。ringpublic

継承

もう一度電話帳を見てみましょう。これは、下位にあるモデルがブランチの上位にあるモデルのすべての特性に加えて、独自の特性を備えている階層を表していることがわかります。たとえば、スマートフォンは通信にセルラー ネットワークを使用し (携帯電話の特性を持ち)、ワイヤレスで持ち運び可能 (コードレス電話の特性を持ち)、通話の送受信が可能 (電話の特性を持ちます) です。この場合、オブジェクトのプロパティの継承について話すことができます。 プログラミングにおける継承とは、既存のクラスを使用して新しいクラスを定義することです。 継承を使用してスマートフォン クラスを作成する例を見てみましょう。すべてのコードレス電話機は充電式バッテリで駆動されており、その動作寿命は数時間です。そこで、このプロパティを無線電話クラスに追加しましょう。
public abstract class WirelessPhone extends AbstractPhone {

    private int hour;

    public WirelessPhone(int year, int hour) {
        super(year);
        this.hour = hour;
    }
    }
携帯電話は無線電話のプロパティを継承するため、このクラスにcallとメソッドの実装も追加しましたring
public class CellPhone extends WirelessPhone {
    public CellPhone(int year, int hour) {
        super(year, hour);
    }

    @Override
    public void call(int outputNumber) {
        System.out.println("Calling a number" + outputNumber);
    }

    @Override
    public void ring(int inputNumber) {
        System.out.println("A subscriber is calling you" + inputNumber);
    }
}
そして最後に、スマートフォン クラスです。これは、従来の携帯電話とは異なり、本格的なオペレーティング システムを備えています。このオペレーティング システムでサポートされる新しいプログラムをスマートフォンに追加して、機能を拡張できます。コードを使用すると、クラスは次のように記述できます。
public class Smartphone extends CellPhone {

    private String operationSystem;

    public Smartphone(int year, int hour, String operationSystem) {
        super(year, hour);
        this.operationSystem = operationSystem;
    }
public void install(String program){
    System.out.println("Installing" + program + "For" + operationSystem);
}

}
ご覧のとおり、Smartphoneクラスを記述するために作成した新しいコードはほとんどありませんでしたが、新しい機能を備えた新しいクラスが得られました。OOP 継承の原則を使用すると、コードの量が大幅に削減されるため、プログラマの作業が容易になります。

ポリモーフィズム

すべての電話モデルを見ると、モデルの外観やデザインの違いにもかかわらず、いくつかの共通の動作を特定することができます。すべての電話は通話の受信と発信が可能で、非常に明確でシンプルな一連のコントロール ボタンを備えています。OOP の基本原理の 1 つ (プログラミング用語での抽象化) を適用すると、電話オブジェクトには 1 つの共通インターフェイスがあると言えます。したがって、電話ユーザーは、デバイスの技術的な詳細に立ち入ることなく、同じコントロール ボタン (機械式またはタッチ式) を使用して、さまざまなモデルを非常に快適に使用できます。そのため、常に携帯電話を使用していて、固定電話の相手から簡単に電話をかけることができます。オブジェクトの内部構造に関する情報がなくても、プログラムが同じインターフェイスを持つオブジェクトを使用できる OOP の原理は、ポリモーフィズムと呼ばれます。私たちのプログラムで、任意の電話モデルを使用して別のユーザーに電話をかけることができるユーザーを記述する必要があると想像してみましょう。その方法は次のとおりです。
public class User {
    private String name;

    public User(String name) {
        this.name = name;
            }

    public void callAnotherUser(int number, AbstractPhone phone){
// here it is polymorphism - using the abstract type AbstractPhone phone in the code!
        phone.call(number);
    }
}
 }
次に、さまざまな電話モデルについて説明します。最初の電話モデルの 1 つ:
public class ThomasEdisonPhone extends AbstractPhone {

public ThomasEdisonPhone(int year) {
    super(year);
}
    @Override
    public void call(int outputNumber) {
        System.out.println("Turn the Handle");
        System.out.println("Give me the phone number, sir");
    }

    @Override
    public void ring(int inputNumber) {
        System.out.println("Phone calls");
    }
}
一般の固定電話:
public class Phone extends AbstractPhone {

    public Phone(int year) {
        super(year);
    }

    @Override
    public void call(int outputNumber) {
        System.out.println("I'm calling a number" + outputNumber);
    }

    @Override
    public void ring(int inputNumber) {
        System.out.println("Phone calls");
    }
}
そして最後に、クールなテレビ電話です。
public class VideoPhone extends AbstractPhone {

    public VideoPhone(int year) {
        super(year);
    }
    @Override
    public void call(int outputNumber) {
        System.out.println("I connect a video channel for the subscriber" + outputNumber );
    }
    @Override
    public void ring(int inputNumber) {
        System.out.println("You have an incoming video call..." + inputNumber);
    }
  }
メソッド内でオブジェクトを作成しmain()、メソッドをテストしてみましょうcallAnotherUser
AbstractPhone firstPhone = new ThomasEdisonPhone(1879);
AbstractPhone phone = new Phone(1984);
AbstractPhone videoPhone=new VideoPhone(2018);
User user = new User("Andrey");
user.callAnotherUser(224466,firstPhone);
// Rotate the knob
// Tell me the number of the subscriber, sir
user.callAnotherUser(224466,phone);
//Call number 224466
user.callAnotherUser(224466,videoPhone);
//I connect the video channel for subscriber 224466
オブジェクトに対して同じメソッドを呼び出すとuser、異なる結果が得られました。callメソッド内の特定のメソッド実装の選択は、callAnotherUserプログラム実行中に呼び出し元オブジェクトの特定のタイプに基づいて動的に行われます。これがポリモーフィズムの主な利点、つまりプログラム実行時の実装の選択です。上記の電話クラスの例では、メソッドのオーバーライドを使用しました。これは、メソッドのシグネチャを変更せずに、基本クラスで定義されたメソッドの実装を変更する手法です。これは本質的にメソッドの置換であり、プログラムの実行時に呼び出されるサブクラスで定義された新しいメソッドです。通常、メソッドをオーバーライドするときは、@Overrideオーバーライドされるメソッドとオーバーライドするメソッドの署名をチェックするようにコンパイラーに指示するアノテーションが使用されます。 したがって、プログラムのスタイルが OOP の概念および OOP Java の原則に準拠していることを確認するには、次のヒントに従ってください。
  • オブジェクトの主な特徴を強調します。
  • オブジェクトの作成時に共通のプロパティと動作を強調表示し、継承を使用します。
  • 抽象型を使用してオブジェクトを記述します。
  • クラスの内部実装に関連するメソッドとフィールドは常に非表示にするようにしてください。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION