CodeGym /Java Blog /ランダム /OOP の原則
John Squirrels
レベル 41
San Francisco

OOP の原則

ランダム グループに公開済み
やあ!今日のレッスンでは、オブジェクト指向プログラミングの原則について話します。Java がなぜそのまま設計されているのか疑問に思ったことはありますか? つまり、クラスを宣言し、クラスに基づいてオブジェクトを作成し、クラスにはメソッドなどがあります。しかし、プログラムが他のものではなくクラスとオブジェクトで構成されるように言語が構造化されているのはなぜでしょうか? なぜ「物」という概念が発明され、前面に押し出されたのでしょうか?すべての言語がこのように設計されているのでしょうか? そうでない場合、Java にどのような利点がありますか? ご覧のとおり、たくさんの質問があります :) 今日のレッスンでそれぞれに答えてみましょう。

オブジェクト指向プログラミング (OOP) とは何ですか?

もちろん、Java は単なる遊びのためのオブジェクトとクラスで構成されているわけではありません。これらは Java の作成者の気まぐれではなく、さらには彼らの発明でもありません。オブジェクトに基づいた言語は他にもたくさんあります。このような最初の言語は「Simula」と呼ばれました。1960年代にノルウェーで発明されました。さらに、Simulaでは「クラス」と「メソッド」という概念が登場しました。ソフトウェア開発の基準からすると、「Simula」は古代の言語のように見えますが、Java との「類似性」は誰でもわかります。オブジェクト指向プログラミングの原則 - 1おそらく、この言語で書かれたコードを簡単に読んで、それが何をするのかを大まかに説明できるでしょう :)

Begin
	Class Rectangle (Width, Height); Real Width, Height;
			           
	 Begin
	    Real Area, Perimeter;  
	 
	    Procedure Update;      
	    Begin
	      Area := Width * Height;
              OutText("Rectangle is updating, Area = "); OutFix(Area,2,8); OutImage;
	      Perimeter := 2*(Width + Height);
              OutText("Rectangle is updating, Perimeter = "); OutFix(Perimeter,2,8); OutImage;
	    End of Update;
	 
	    Update;               
	    OutText("Rectangle created: "); OutFix(Width,2,6);
	    OutFix(Height,2,6); OutImage;
	 End of Rectangle;

       Rectangle Class ColouredRectangle (Color); Text Color;
			           
	Begin   	  
	    OutText("ColouredRectangle created, color = "); OutText(Color);
	    OutImage;
        End of ColouredRectangle;

 
      	 Ref(Rectangle) Cr;            
	 Cr :- New ColouredRectangle(10, 20, "Green"); 
End;
このコード サンプル コードは、 Weekly-geekly の「Simula - 50 years of OOP」から引用したものです。ご覧のとおり、Java はその祖先とそれほど違いはありません :) これは、Simula の登場が、オブジェクト指向プログラミングという新しい概念の誕生を示したという事実によるものです。Wikipedia では、OOP を次のように定義しています。 「オブジェクト指向プログラミング (OOP) は、フィールド (属性として知られる) の形式でデータを含めることができる「オブジェクト」の概念に基づいたプログラミング パラダイムです。手順 (メソッドとして知られることも多い) のこと。」私の意見では、これは非常に良い定義です。あなたが Java を学び始めたのはそれほど前のことではありませんが、この定義にはおそらくあなたが知らない単語は含まれていません :) 現在、OOP は最も一般的なプログラミング手法です。Java以外にも、OOP の原則は、聞いたことがある多くの一般的な言語で使用されています。たとえば、C++ (ゲーム開発で積極的に使用されています)、Objective-C と Swift (Apple デバイス用のプログラムを作成するために使用されます)、Python (機械学習で最も人気があります)、PHP (最も人気のある Web 開発言語の 1 つ)、JavaScript (何に使われないかを言うのは簡単です) などなど。では、そもそも OOP の原則とは何でしょうか? 詳しくお伝えします。そもそも OOP の原則とは何ですか? 詳しくお伝えします。そもそも OOP の原則とは何ですか? 詳しくお伝えします。

OOP の原則

これらは基礎中の基礎です。オブジェクト指向プログラミング パラダイムを形成する 4 つの主な機能。それらを理解することは、プログラマーとして成功するために不可欠です。

原則 1. 継承

良いニュースです。あなたはすでに OOP の原則の一部を知っています。:) 私たちはすでにレッスンで何度か継承に遭遇しており、なんとか使用することができました。継承は、既存の (親) クラスに基づいて新しいクラスを記述するためのメカニズムです。その際、新しいクラスは親クラスのプロパティと機能を借用します。継承は何のためにあり、どのような利点をもたらしますか? 何よりも、コードの再利用です。親クラスで宣言されたフィールドとメソッドは、子孫クラスでも使用できます。すべてのタイプの自動車に 10 個の共通フィールドと 5 個の同一のメソッドがある場合、それらをAuto フィールドに移動するだけで済みます。親クラス。子孫クラスでも問題なく使用できます。確かな利点: 量的 (コードが少なくなる) と、結果として定性的 (クラスがはるかにシンプルになる) の両方です。さらに、継承は非常に柔軟です。子孫に欠けている機能 (特定のクラスに固有の一部のフィールドや動作) を個別に書き込む機能を追加できます。一般に、実生活と同じように、私たちは皆、両親にいくらか似ていますが、どこか違うところもあります:)

原則 2. 抽象化

これは非常に単純な原理です。抽象化とは、何かの主な最も重要な特徴を特定すると同時に、マイナーで重要でないものをすべて破棄することを意味します。車輪を再発明する必要はありません。クラスに関する古い授業の例を思い出してみましょう。会社の従業員向けのファイル システムを作成しているとします。「従業員」オブジェクトを作成するために、従業員クラスを作成しました。会社のファイリングシステムでそれらを説明するにはどのような特徴が重要ですか? 名前、生年月日、SSN、従業員 ID。しかし、この種の記録に従業員の身長、目の色、髪の色が必要になる可能性は低いです。会社は従業員に関するそのような情報を必要としません。したがって、Employeeクラスで次の変数を宣言します。int ageint socialSecurityNumber、およびint memberId。そして目の色などの不要な情報を抽象化します。しかし、モデル事務所向けのファイリングシステムを作成する場合、状況は劇的に変わります。モデルの身長、目の色、髪の色は重要な特徴ですが、彼女の SSN は私たちにとってまったく無関係です。したがって、Modelクラスで次の変数を作成します: String heightString HairString eye

原則 3. カプセル化

私たちはすでにこの問題に遭遇しています。Java では、カプセル化とは、データの読み取りおよび変更の機能を制限することを意味します。ご覧のとおり、この用語は「カプセル」という単語に基づいています。「カプセル」を使用して、他の人に変更されたくない重要なデータを隠します。ここでは実際の生活からの簡単な例を示します。あなたには姓と名があります。あなたの友達はみんな知っています。しかし、彼らはあなたの姓名を変更することはできません。そのためのプロセスは裁判所システムによって「カプセル化」されていると言えるかもしれません。姓を変更できるのは裁判所書記官を通してのみであり、変更できるのはあなただけです。他の「ユーザー」はあなたの姓名への「読み取り専用」アクセス権を持っています:) 別の説明的な例は、自宅に保管されている現金です。部屋の真ん中に目立つところに置いておくのは得策ではありません。「ユーザー」(あなたの家に来る人)は誰でも、あなたのお金の金額を変更することができます。つまり、彼らはあなたのお金を受け取ることができます。金庫にカプセル化した方が良いでしょう。そうすれば、特別なコードを使用した場合にのみ、あなただけがアクセスできるようになります。すでに扱ったことのあるカプセル化の明白な例としては、アクセス修飾子 (プライベート、パブリックなど)、およびセッターとゲッターが挙げられます。カプセル化しない場合は、Catクラスのageフィールドを使用すると、誰でも次のように書くことができます。

Cat.age = -1000;
カプセル化メカニズムにより、セッター メソッドを使用して ageフィールドを保護できるようになり、age を負の数に設定できないようにすることができます。

原則 4. ポリモーフィズム

ポリモーフィズムは、複数の型を同じ型であるかのように操作できる機能です。また、オブジェクトの動作はその種類によって異なります。それは複雑に聞こえますか? 今すぐ意味を理解しましょう。最も単純な例として動物を考えてみましょう。1 つのspeech()メソッドと 2 つのサブクラス ( CatおよびDog )を含むAnimalクラスを作成します。

public class Animal {

   public void speak() {
      
       System.out.println("Hello!");
   }
}

public class Dog extends Animal {
  
   @Override
   public void speak() {
       System.out.println ("Woof-woof!");
   }
}

public class Cat extends Animal {

   @Override
   public void speak() {
       System.out.println("Meow!");
   }
}
次に、 Animal参照変数 を宣言し、それに Dogオブジェクトを割り当ててみます。

public class Main {

   public static void main(String[] args) {

       Animal dog = new Dog();
       dog.speak();
   }
}
どのようなメソッドが呼び出されると思いますか? Animal.speak()またはDog.speak() ? Dogクラスのメソッドは次のように呼ばれます: Woof-woof! Animalリファレンスを作成しましたが、オブジェクトはDogのように動作します。必要に応じて、猫、馬、その他の動物のように振る舞うこともできます。重要なことは、特定のサブクラスを一般的なAnimal参照変数に割り当てることです。すべての犬は動物であるため、これは当然のことです。これが、「オブジェクトの動作はタイプに応じて異なる」というときに私たちが念頭に置いたことです。Catオブジェクトを作成すると...

public static void main(String[] args) {

   Animal cat = new Cat();
   cat.speak();
}
speech ()メソッドは「ニャー!」と表示します。しかし、「複数のタイプを同じタイプであるかのように扱う能力」とは何を意味するのでしょうか? これも非常に簡単です。動物用の理髪店を作成していると想像してみましょう。私たちの理髪店はどんな動物でもトリミングできる必要があるため、Animalパラメーター (ヘアカットを受ける動物) を指定してTrim()メソッドを作成します。

public class AnimalBarbershop {

   public void trim(Animal animal) {

       System.out.println("The haircut is done!"); 
   }
}
これで、CatオブジェクトとDogオブジェクトをTrim()メソッドに渡すことができるようになりました。

public static void main(String[] args) {

   Cat cat = new Cat();
   Dog dog = new Dog();

   AnimalBarbershop barbershop = new AnimalBarbershop();

   barbershop.trim(cat);
   barbershop.trim(dog);
}
そして、これが明確な例です。AnimalBarbershopクラスは、CatタイプとDogタイプ同じタイプであるかのように処理します。同時に、犬は異なる行動をし、それぞれ異なる話し方をします。

なぜ OOP が必要なのでしょうか?

なぜ OOP が新しいプログラミング概念として生まれたのでしょうか? プログラマーは手続き型言語などの機能するツールを持っていました。彼らが根本的に新しいものを発明するきっかけとなったのは何でしょうか? 何よりも、彼らが直面したタスクの複雑さ。60 年前、プログラマーのタスクが「いくつかの数式を評価する」のようなものだったとすると、今では「ポイント A、B、C、DE で行われたプレイヤーの決定の組み合わせに応じて、ゲーム STALKER に 7 つの異なるエンディングを実装する」といったものになる可能性があります。 、ゲーム内のF。」ご覧のとおり、過去数十年でタスクは明らかに複雑になってきました。その結果、データ型はより複雑になりました。これが OOP が登場したもう 1 つの理由です。通常のプリミティブを使用して数式を簡単に評価できます。ここではオブジェクトは必要ありません。しかし、ゲームのエンディングに関するタスクは、カスタム クラスを使用せずに記述することさえ困難です。とはいえ、クラスとオブジェクトを使用して記述するのは非常に簡単です。明らかに、Game、Stalker、Ending、PlayerDecision、GameEvent などのいくつかのクラスが必要になります。つまり、問題を解き始めなくても、頭の中で解決策を簡単に「描く」ことができるのです。タスクがますます複雑になるため、プログラマーはタスクを複数の部分に分割する必要がありました。しかし、これを手続き型プログラミングで行うのはそれほど簡単ではありませんでした。そして、多くの場合、プログラムは、考えられるすべての実行パスを表す多数の枝を持つツリーのようなものでした。特定の条件に応じて、プログラムのいずれかの分岐が実行されました。小さなプログラムの場合、これは便利でしたが、大きな問題を部分に分割するのは非常に困難でした。これが OOP の出現のもう 1 つの理由でした。このパラダイムにより、プログラマーはプログラムを多数の「モジュール」(クラス) に分割し、それぞれが独自の作業部分を実行できるようになりました。すべてのオブジェクトは相互に対話することにより、プログラムの作業を実行します。さらに、プログラム内の他の場所でコードを再利用できるため、時間を大幅に節約できます。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION