Upgrade to Pro — share decks privately, control downloads, hide ads and more …

サブ資料①オブジェクト指向の基礎

Recruit
August 10, 2023

 サブ資料①オブジェクト指向の基礎

2023年度リクルート エンジニアコース新人研修の講義資料です

Recruit

August 10, 2023
Tweet

More Decks by Recruit

Other Decks in Technology

Transcript

  1. 1 ページ サブ資料①:オブジェクト指向の基礎 オブジェクトの基本原則 『オブジェクトは属性(データ)と振る舞い(関数・メソッド)を持つ』 オブジェクト指向プログラミングでは、現実世界の物事や概念をオブジェクトとしてモデル化し、 オブジェクトは、その特性や状態を表す属性(データ)を持ち、それに対して操作や振る舞いを⾏ うためのメソッドを提供する。 (次ページに続く) オブジェクト指向⾔語の構成要素:クラス

    / インスタンス / オブジェクト オブジェクト指向プログラミングにおいて、共通のプロパティとメソッドを持つオブジェクトの設 計図となるもので実際のオブジェクトを⽣成する際に利⽤され、メモリの静的データ領域にロード される。 クラス(Class) インスタンス(Instance) オブジェクト(Object) オブジェクト指向プログラミングにおいて、データと処理を⼀体化したもので、クラスから⽣成された インスタンスのことを指す。⼀般に、インスタンスとオブジェクトは同義語として使われることが多い 設計図であるクラスから⽣成され、実際にメモリ(ヒープ領域)上に確保されるオブジェクトを指 す。あるクラスから別々に⽣成された複数のインスタンスは、それぞれ独⽴したメモリ領域に格納 される。 オブジェクト指向の考え⽅ オブジェクト指向は、プログラムの構造を分割し、それぞれのオブジェクトが特定の責任を持つよ うにすることで、複雑な問題を解決する⼿法で、現実世界の要素や概念をプログラム内のオブジェ クトとして表現することで、プログラムの設計や実装をより理解しやすく、柔軟性のあるシステム の構築を可能にする。 オブジェクト指向では、各オブジェクトがデータと振る舞いを持ち、他のオブジェクトと相互作⽤ することでシステムが構築される。オブジェクトはそれぞれが独⽴して存在し、⾃⼰の状態を持ち、 他のオブジェクトとメッセージのやり取りを⾏う。 オブジェクト指向は抽象化、カプセル化、継承、ポリモーフィズムといった概念や原則を⽤いて、 プログラムをより柔軟に設計することが可能。これにより、コードの再利⽤性や拡張性が⾼まり、 ⼤規模なシステムの開発においても効果的な⼿法となっている。
  2. 2 ページ 属性はオブジェクトの状態や特徴を表現し、オブジェクトの状態が変化することで属性の値も変化 する。例えば、⾞のオブジェクトでは、⾊や速度などが属性となる。 ⼀⽅、振る舞いはオブジェクトが⾏う操作や機能を表現する。オブジェクトは他のオブジェクトと の相互作⽤を通じて振る舞いを実現する。例えば、⾞のオブジェクトでは、加速や停⽌といった振 る舞いを持つ 継承 継承とは、あるクラス(継承元、親クラス、スーパークラス)の特性や振る舞いを別のクラス (継承先、⼦クラス、サブクラス)が引き継いで利⽤することを意味する。

    継承を通じて、既存のクラスを拡張し、共通の特性や振る舞いを再利⽤することが可能。 継承の関係では、「継承先は継承元の⼀種である(is-a 関係)」と⾔え、例えば、継承元が「動 物」というクラスであり、継承先が「⽝」というクラスであれば、「⽝は動物である」と⾔えま す。 なお、Javaでは、単⼀継承(クラスが1つの親クラスからのみ継承できる)がサポートされてお り、多重継承(1つ以上の親クラスからの継承)は禁⽌されている。 ★インターフェース 継承は縦の関係(階層関係)を表し、クラスの階層を形成する。継承元のクラスが継承先のクラス の基盤となり、継承先は継承元の特性や振る舞いを受け継ぐことができる。これにより、継承先は 継承元の機能を拡張したり、振る舞いを上書きすることが可能。 ⼀⽅、インターフェースは横の関係(※同じ服を着る等の共通点を持つニュアンスでの横関係)を 表し、クラスが提供する契約(抽象メソッドの宣⾔)を定義する。インターフェースは実装側がそ の契約を遵守することで、異なるクラス間で共通の振る舞いを実現する⼿段となる。クラスは複数 のインターフェースを実装することができ、それぞれのインターフェースで定義されたメソッドを 実装する必要がある。 (次ページに続く) 親クラス 親クラスの機能 ⼦クラス 親クラスの機能 ⼦クラスの機能 継承
  3. 3 ページ インターフェースの(⼤規模開発における)重要性 インターフェースを使⽤することで、モジュールの結合度を弱くし、変更に強い設計を実現する ことができる。 インターフェースによって境界を定めることで、各モジュールはそのインターフェースに従って コミュニケーションを⾏う。各モジュールは⾃⾝の内部実装を隠蔽し、他のモジュールが必要な 機能に対してはインターフェースを通じて提供するため、これにより、モジュール間の結合度が 低くなり、あるモジュールの変更が他のモジュールに影響を与えにくくなる ⼤規模開発では、機能の追加や変更が頻繁に⾏われることがあり、その際、インターフェースに

    よってモジュール間の契約が明確になっているため、変更が⽣じた場合でも関連するモジュール の修正が容易になる。また、モジュールの独⽴性が⾼まるため、単体でのテストや再利⽤も容易 になります。 したがって、インターフェースを使⽤することで、⼤規模開発において変更に強く、モジュール 結合度が弱くなるというメリットがある 継承 or インターフェース 継承は適切に使⽤しないと複雑な階層構造やクラス間の強い結合が⽣じる可能性があり、イン ターフェースはそれを実装したクラス間の緩い結合と柔軟性を提供するため、インターフェース をなるべく使うのが望ましい モジュール結合度と凝集度 モジュール結合度 プログラムの健全度を表す概念としてモジュール結合度と凝集度が挙げられる ⼀般的にモジュール結合度は低く、凝集度は⾼い⽅が良い(⾼凝集・疎結合) モジュール結合度(Coupling)は、モジュール間の依存度や結びつきの度合いを表す。結合度が 低い場合、モジュール間の依存が少なく、変更が発⽣した場合でも他のモジュールに影響を与え にくくなる。疎結合なモジュールは、単独でのテストや再利⽤が容易であり、システム全体の柔 軟性や保守性を⾼める (次ページに続く)
  4. 4 ページ モジュール凝集度 同じクラスやパッケージ等に同類の役割のモジュールや処理が集まっているかどうか 凝集度(Cohesion)は、モジュール内の要素がどれだけ密に関連しているかを表す。凝集度が⾼ い場合、モジュール内の要素が⼀つの責務や⽬的に集中しており、役割が明確になっている。ま た同じようなモジュールがパッケージ内に集まっている場合でも、それらが共通の⽬的や関⼼事 に関連しているのであれば、⾼凝集といえる。⾼凝集なモジュールは、機能の追加や変更が容易 であり、モジュール内の理解や保守がしやすくなる ポリモーフィズム(多態性

    / 多相性 ) ポリモーフィズムは、オブジェクト指向の重要な特性であり、ソフトウェアの柔軟性、拡張性、 保守性を⾼めるために利⽤される。正しく活⽤することで、コードの効率性や再利⽤性を向上 させ、複雑なシステムをより理解しやすくすることができる。 ポリモーフィズムは、同じメソッド名を持つ異なるオブジェクトが、それぞれ固有の実装を持 つことによって、異なる動作を実現する機能です。具体的には、親クラスやインターフェース を共有する複数のサブクラスがあり、それぞれが同じメソッド名を持つ場合にポリモーフィズ ムが発揮されます。 カプセル化 カプセル化は、オブジェクトの内部の状態や振る舞いを隠蔽し、外部からのアクセスを制限する こと。オブジェクトは⾃⾝の内部にデータを保持し、そのデータに対する操作をメソッドを通じ て提供する。これにより、データの状態を安全に保ちながら、外部からの不正な変更やアクセス を防ぐことが可能になる しかしながら、完全に結合度をゼロにすることや、完全に凝集度を最⼤化することは現実的では なく、設計上のトレードオフが存在することも多く、特定の状況や要件に応じて最適なバランス を⾒つける必要がある 現実世界 Java サイレン サイレンを鳴らす(機能) Siren siren; void soundSiren(); public class Car { // ⾃動⾞の機能 ... } public class PoliceCar extends Car { privateSiren siren; public void soundSiren() { this.siren.sound(); } }
  5. 5 ページ オーバーライド オーバーライド(Override)は、ポリモーフィズムの⼀形態でサブクラス(派⽣クラス)がスー パークラス(基底クラス)のメソッドを再定義することを意味する。サブクラスは基本スーパーク ラスのメソッドを継承するが、そのメソッドの振る舞いを変更(上書き)する必要がある場合に オーバーライドを使⽤する。 具体的には、スーパークラスで定義されたメソッドと同じシグネチャ(メソッド名、引数の型およ び順序)を持つメソッドをサブクラスで再度定義し、そのメソッドの実装をオーバーライドする。 これにより、サブクラスで新しい実装を提供することができる。

    オーバーロード オーバーロード(Overload)は、静的なポリモーフィズムの⼀形態で、同じメソッド名を持つが、 引数の型、数、および順序が異なる複数のメソッドを定義することを指す。これにより、同じ 名前のメソッドを異なる引数で呼び出すことができるようになるため、同じ操作や処理の異な るバリエーションを提供することができる。 public class Computer { ... public void initialize(String env) {...} public void initialize(int archType) {...} public void initialize(String env, int archType) {...} public void initialize(int archType, String env) {...} ... } 同じメソッド名でも引数の型、 個数または並びが異なってい るので、別のメソッドとして みなされる 親クラス void execute() { 処理 A; } ⼦クラス void execute() { 処理 B; } 継承 オーバーライド メソッドのオーバーロードの例
  6. 6 ページ キャスト 明⽰的キャスト キャスト (Cast) は、プログラムにおいてデータ型の変換を⾏う操作のことで、明⽰的キャストと 暗黙的キャストの2種類がある 暗黙的キャスト 抽象型とは

    抽象型は、例えば、継承元の親クラスの型やインターフェースの型を指し、ポリモーフィズムの 実現やコードの再利⽤性の向上に貢献する。抽象型を使⽤することで、異なる具体的な型のオブ ジェクトを統⼀的に扱うことができ、また、抽象型を継承したり実装したりすることで、共通の インターフェースや振る舞いを持つクラスを効率的に作成することができる。 例えば以下のAutomobileというinterfaceを実装したTruckとSedanのオブジェクトは同じAutomobile という抽象形で表現できる 以下はどちらもAutomobile Automobile truck = new Truck(); Automobile sedan = new Sedan(); プログラマが明⽰的にキャスト演算⼦を使⽤して型変換を⾏う操作で、データの精度や範囲の損 失が発⽣する可能性があるため、注意が必要。 また、明⽰的キャストは呼び出し元と呼び出し先のモジュール間の結合度を低く抑える上で、な るべく多⽤しないことが望ましい // 暗黙的キャスト Automobile truck = new Truck(); // 明⽰的キャスト Truck truck = (Truck)truck; 暗黙的キャストは、コンパイラによって⾃動的に⾏われるデータ型の変換で、プログラムの可読 性を向上させ、コードを簡潔に保つことができ、モジュール結合度を低める傾向がある。しかし、 暗黙的なキャストが⾏われる場合でも、データの損失や予期しない結果が発⽣する可能性がある ため、注意が必要。
  7. 7 ページ ポインタはメモリ上の特定のデータのアドレスを直接⽰す変数で、ポインタはそのアドレスを通 じてデータにアクセスすることができる。CやC++などの⾔語ではポインタが使⽤され、メモリ の直接的な制御や効率的なデータ操作が可能になっている。 参照型 プリミティブ型 プリミティブ型は基本的なデータ型であり、数値、⽂字、真偽値などの単⼀の値を表す。⼀般的 なプリミティブ型には、整数型(int、long)、浮動⼩数点型(float、double)、⽂字型(char)、 真偽値型(boolean)などがあるが、プリミティブ型の変数は、その値そのものを直接格納する。

    ⼀⽅、参照型の変数は、オブジェクトへの参照値を格納する。参照型の変数が実際に保持してい るのは、オブジェクトへの参照(リンク)であり、その参照を通じてオブジェクトのメソッドや プロパティにアクセスすることができる。 ポインタ・参照値 ポインタ 参照値は変数やオブジェクトへの別名(エイリアス)として機能する値。参照値は元の変数やオ ブジェクトを参照し、同じデータに対して別の名前を提供する。JavaやC#などの⾔語では参照値 が使⽤され、参照値を通じてオブジェクトにアクセスすることで、データの共有やオブジェクト の操作が可能になっている。 ポインタとの違いは、つまり参照値はオブジェクトのメモリのアドレスと変数の間を仲介する間 接的な値であり、ポインタは直接的なアドレス値を持つ値である 参照値 参照型とプリミティブ型 参照型とプリミティブ型は、プログラミング⾔語における変数のデータ型の2つの主要なカテゴ リに該当する プリミティブ型と参照型の違いは、変数が直接的な値を格納するか、参照を格納するかという点 で、それにより、値のコピーと変更の挙動などが異なることに注意
  8. 8 ページ Java 8以降のJava⾔語 Kotlin Scala Groovy Swift 関数型インターフェース 最近の流れとして関数型のインターフェースについても取り⼊れられてきている

    関数が値を返すために、副作⽤を抑えやすい オブジェクト指向と関数型の両⽅の⻑所を取り⼊れる⽅向でオブジェクト指向⾔語が進化している 関数型の特徴 ・出⼒は⼊⼒のみによって決まる ・関数内部に状態を持たない(状態レス) ・関数同⼠が、互いに依存せず、疎結合としやすい 関数型インターフェースを持つ主な⾔語 スクリプト系⾔語でも多くが関数型プログラミングの機能を備えている JavaScript、Lua、Perl、Python、PHP、Ruby