Presentation is loading. Please wait.

Presentation is loading. Please wait.

オブジェクト指向の考え方 竹内 亮太.

Similar presentations


Presentation on theme: "オブジェクト指向の考え方 竹内 亮太."— Presentation transcript:

1 オブジェクト指向の考え方 竹内 亮太

2 はじめに この資料は、オブジェクト指向プログラミングの理解を補助するためのものです
世の中には「オブジェクト指向とは何か」を 説いた書籍や資料は多いですが、オブジェクト指向への移行の仕方や、その具体的な意味や 意義について述べたものは少ないのが実情です なので、作ってみました

3 前提知識 プログラミング演習の内容は大前提です Java言語に限定した内容ではありません 変数とは何か 配列とは何か メソッドとは何か
引数や返値までしっかり復習すること その他、条件分岐や繰り返しの構文 Java言語に限定した内容ではありません C++言語などにも応用できます

4 理解のフェイズ オブジェクト指向は、フェイズ(段階)に 分けて理解していくことをおすすめします
自分に理解できて応用できそうな要素を、 段階を踏んで導入していけばよいでしょう 一度理解したフェイズも、時間をおいて 復習してみましょう 理解の質が変わってくるはずです

5 変数のおさらい 値を覚えておくための箱のようなもの 1つの箱に1つだけ、値を入れておける 入れる値の種類に応じて、違う型を使う
整数なら int 型、実数なら double 型など int iA = 12; iA int型 12

6 変数の限界 変数1つには、1つの値しか入れられない だが実際には、1つの数値だけでは表しきれない物事が多数存在する
例:RPGのキャラクターステータス 名前、職業、レベル、HP、MP、力、素早さ、etc… 例:三角形や長方形などの図形情報 幅と高さ、のように複数の値でないと表現不可

7 キャラクターを表現してみよう 右のようなステータス画面のゲームの場合 だいたいこんな感じでできています 剣士子
String sName = “剣士子”; String sClass = “Swordman”; int iLevel = 4; int iExp = 0; int iNowHP = 150; int iMaxHP = 150; int iStr = 31, iVit = 28; int iDex = 14, iAgl = 11; int iInt = 7, iWis = 10; だいたいこんな感じでできています 剣士子 Swordman

8 キャラクターは1人じゃない さっきのゲームが4人パーティでプレイするゲームだったとする あと3人分も、あんな感じで変数を用意するのか?
…やってらんねぇ! String charaB_sName = “エルフっ娘”; String charaB_sClass = “Archer”; int charaB_iLevel = 54; int charaB_iExp = 65535; int charaB_iNowHP = 420; int charaB_iMaxHP = 420; int charaB_iStr = 123, charaB_iVit = 119; int charaB_iDex = 241, charaB_iAgl = 180; int charaB_iInt = 176, charaB_iWis = 155; ↑これがあと2キャラ分必要になる

9 「クラス」の誕生 複数の値で何か1つの対象を表す時に、 その値をまとめておきたい
まとめた上で、そのまとまったものを 「1つの変数として」扱えたら便利かも? じゃあ必要な変数をまとめたものを 「クラス」と呼ぶことにしよう 作ったクラスは int や double みたいに、 「変数の型の1種類」として 扱えることにしよう

10 クラスの作り方 だいたい授業で説明したとおり この段階では、まだ 「新しい型の変数の箱」を 設計した(デザインした)だけにすぎない
public class Character { public String sName; public String sClass; public int iLevel, iExp; public int iNowHP, iMaxHP; public int iStr, iVit, iDex, iAgl, iInt, iWis; } この段階では、まだ 「新しい型の変数の箱」を 設計した(デザインした)だけにすぎない

11 クラスの使い方 「クラス型変数」には、自分で決めた「メンバ変数」の分だけ、別々に値をしまうことができる こうやって使う
Character charaA = new Character(); charaA.sName = “剣士子”; 以下のようなイメージ(一部メンバ変数だけ抜粋) String型 String型 int型 int型 int型 sName sClass iLv iHP iStr Character型 charaA

12 量産しよう、そうしよう 一回作ったクラスは、いくらでも量産して 使い回しが可能 変数1つでキャラクター1人を表せている
Character charaB = new Character(); Character charaC = new Character(); Character charaD = new Character(); 変数1つでキャラクター1人を表せている String型 Character型 int型 sName sClass iLv iHP iStr charaB String型 Character型 int型 sName sClass iLv iHP iStr charaC String型 Character型 int型 sName sClass iLv iHP iStr charaD

13 フェイズ1:クラスとは 何かを表すための値の集まり 作ったクラスを利用する時は、 として、クラス型変数を宣言して利用する
値の集まりを、1つの変数のように扱える クラスを作るということは、オリジナルの変数の箱をデザインするようなもの 作ったクラスを利用する時は、 クラス名 変数名 = new クラス名(); として、クラス型変数を宣言して利用する こうして作ったクラス型変数を 「インスタンス」と呼ぶ インスタンスを作ることを「実体化」とも言う

14 値をまとめたその次は 例:キャラクターのレベルアップ処理 いちいち「charaA.~」とするのは面倒
charaA.iLevel++; charaA.iMaxHP+=20; charaA.iStr+=5; いちいち「charaA.~」とするのは面倒 charaBに対しても同じように書かなくては ならないなら、値をまとめた意味が薄くなる 値をまとめたら、それに関する処理も まとめたくなってくる むしろまとめるべき

15 メソッド化しよう クラスのメンバに関する処理は、 可能な限りメソッド化する レベルアップ処理のメソッド 呼び出し側からの呼び出し
public void incremntLevel() { iLevel++; iMaxHP+=20; iStr+=5; } 呼び出し側からの呼び出し charaA.incremntLevel(); // charaA がレベルアップ charaB.incremntLevel(); // charaB がレベルアップ

16 メソッド化のメリット 同じような処理を何度も書かずに済む メンバ変数を好き勝手にいじらせない お決まりの手続きを1回の呼び出しで済ませる
複数のオブジェクトに対しても、呼び出し一発 メンバ変数を好き勝手にいじらせない メソッドの中で値をチェックすることで、 入れて欲しくない値を弾くことができる HPがマイナスになったらまずい、などなど

17 直接操作と間接操作 例:ダメージを与える処理 HPが20の時に、50のダメージが当たった メソッドを使わない場合
charaA.iNowHP-=50; // 現在HPが-30になる メソッド化した場合 public void damage(int argDmg) { iNowHP-=argDmg; if(iNowHP < 0) { iNowHP = 0; } ~~(↑はクラスの内部・↓は呼び出し側)~~ charaA.damage(50); // マイナスになる心配がなくなる!

18 アクセス制御 せっかくメソッドを用意しても、どこかで直接値をいじられたら意味がない
クラスの外からいじれるもの、いじって 欲しくないものを分ける必要が出てくる 外からいじってもいいメンバには public を型の前につける 外からいじられたくないメンバには private を型の前につける

19 全部 public じゃダメなん? ダメです 基本的に変数は private にしておく
小規模なプログラムでは問題ないですが、 好き勝手にいじれる状態にしておくと、 後々混乱の原因になります 基本的に変数は private にしておく 各変数に対しては、値をセットしたり返してくれたりするメソッドを public で用意しておく メンバ変数を読み書きするためのメソッドを、setter や getter と呼ぶ

20 いちいち set したり get したり 面倒ですよね
本来ならば、間に値をチェックしたりする必要がなければ、直接代入したり参照しても構いません(クラスの利用目的にもよります) ですが、今は練習がてらアクセッサ(setter & getter)を作る作業をして、慣れてください

21 特別なメソッド:コンストラクタ クラス型変数を new するのと同時に、 入れておきたい値、しておきたい処理を 書いておくメソッド
キャラクターなら、レベル1のステータスを 入れておきたい、など クラスと同じ名前のメソッドを作ると、 それがコンストラクタになる 返値の型は指定しない コンストラクタは引数を取れる 引数を付けたら、new する時に引数を渡す必要がある

22 コンストラクタの例 キャラクターを作る時に、名前と職業だけ決めて、後のメンバ変数にはレベル1の ステータスをセットしたい
// コンストラクタの作成例 public Character(String argName, String argClass) { sName = argName; sClass = argClass; iLevel = 1; } ~~(↑はクラスの内部・↓は呼び出し側)~~ // new する側はこんな感じ Character charaA = new Character(“エルフたん”, “Archer”);

23 フェイズ2:メソッドとアクセス制御 クラスのメンバ変数に対する処理をまとめたものを、メソッドと呼ぶ
メンバ変数とメソッドを持つことで、 クラスの本来の意義が完成する メンバ変数へのアクセスはメソッドを 通じて行い、直接いじったりはしない それを徹底させるため、public や private などのキーワードを指定し、アクセスを制御する new するついでに色々やらせることが可能 コンストラクタ

24 次のフェイズに向けて 次のフェイズはちょっと次元跳躍します これまでの内容でも、オブジェクト指向のメリットは大きいはずです
十分プログラムの書き方は効率的になってます ですが、これからが真骨頂です しっかり復習してから進みましょう

25 色んなものをクラスで表そう 例:図形 例:RPGのキャラクター 三角形 長方形 円 直方体 球 円錐 … 戦士 ナイト 僧侶 魔法使い
ハンター 盗賊 アサシン 司祭 賢者 パラディン

26 共通点があるもの多いよね? 図形は全て「図形」という括りにできる 職業も、全て「キャラクター」で括れる
更に言うなら平面図形と立体図形に分けられる 職業も、全て「キャラクター」で括れる 更に言うなら、各職業には「上位」のものが あったりする ナイト→パラディン 僧侶→司祭 魔法使い→賢者

27 もっとクラス化を効率よく 考え方その1 考え方その2 共通点だけを括りだしてクラスにする
例:「図形」という抽象的なクラス それに個別のメンバを足して、「継承」したクラスを作る 例:「三角形・直方体」などの具体的なクラス 考え方その2 基本的な機能(能力)だけを持ったクラス 例:「ナイト・僧侶・魔法使い」など それを「継承」し、追加機能(能力)を持たせたクラス 例:「パラディン・司祭・賢者」など

28 表現する物事を体系化する 図形 キャラクター 平面図形 立体図形 ナイト 僧侶 魔法使い ハンター シーフ 長方形 三角形 円 直方体 円錐
キャラクター ナイト パラディン 僧侶 司祭 魔法使い 賢者 ハンター レンジャー シーフ アサシン

29 「継承」のメリット 共通部分をわざわざ書かなくてよい こういうことができる↓ 付け加えたり、置き換えたい部分だけ作る
変数の追加 メソッドの追加 メソッドの置き換え こういうことができる↓ 継承元クラス 変数名 = new 継承先クラス(); 図形 shape = new 長方形(); ナイト chara0 = new パラディン(); 子は親の一種として扱うことができる

30 続きは本編で 本編の深度に応じて続きも書きます


Download ppt "オブジェクト指向の考え方 竹内 亮太."

Similar presentations


Ads by Google