0.はじめに
Javaを大学で学んでおります。
概念や特徴を以下の文類に分けてまとめました。
関連学習
【Java】用語
【Java】メソッド・型
【Java】オブジェクト指向
【Java】インスタンス・コンストラクタ
【Java】例外処理
【Java】注意点・ルール
【Java】コードの記述向上にむけて(個人用memo)
1.3大構成
オブジェクト指向は以下3点による構成がされる
継承
多様性
カプセル化
2.オブジェクト指向について
これまで学んだ文法や計算方法というのは車でいう設計書のようなもの
オブジェクト指向とはどうすれば車を作り出すことができるのかという考え方に則る
ゴールから逆算して考えるため、どうすれば正解にたどりつけるか
数字の10
を1
と9
を使用する際は "足し算を使えばいい"といった
正解を導き出すための思考が必要
そもそもオブジェクトとは
クラスを実体化したものや仮想世界で活動するモノの総称
データと手続きを一体化(カプセル化)して定義利用するものなど
フィールドを参照しインスタンス(実体)を生成した場合
そのインスタンスそのもののことや、配列における本体のことを
オブジェクトと呼ばれる
メリット
現実世界のモノを仮想世界内でも忠実に再現することが可能
人間が内容を把握しやすくし開発ができるためラクをすることができる
手続き型の違い
手続きは一行ずつそれぞれ書いていき、何をしようかと試行錯誤を繰り返すが
オブジェクト指向は必要なものを抽出し構築をしていく
その必要な要素それぞれを連携させ設計図を書いていく
リアルな設計処理実行をコード内でも実現すればいいという考え方
オブジェクト指向と非オブジェクト指向
明確な思想に基づいてクラスが設計される
RPGを作成する場合は
- 勇者が必要
-
敵が必要
といったようにそれぞれのメソッドが味を出し現実の世界で動いていく
非オブジェクト指向は都合でクラスが設計されていくだけである指向
オブジェクトだけ生成する方法もある
オブジェクト生成だけでも実際は可能だが
クラスを生成しオブジェクトを生成した場合のメリットとして
オブジェクトを何度も生成をすることが可能となる
1つのクラスを生成してからオブジェクト生成をしたほうが良い場合があるということ
オブジェクトは曖昧な存在
クラスのことをオブジェクトと指す場合もあるし
インスタンスというワードを使用する場合もある
インスタンス:車で言う車体
あるクラスを基に作られた具体的なオブジェクトそのもの
オブジェクト:クラスを実体化したもの、仮想世界で活動するもの
データと手続きを一体化(カプセル化)して定義利用するものがオブジェクト
3.クラスとは
設計書のようなもの
オブジェクトの集合体である
どのような属性や操作をもっているか記述するもの
勇者と敵が戦うプログラムを作る場合、
両者共に作成をした場合何かの指示がないと戦ったり動いたりすることができない
そのためMainメソッド
を起動源として動かせて戦わせたりする
1.Mainメソッドを最大クラス
2.勇者クラス、敵クラスは登場人物のクラス
3.Mainメソッドで指示を出し、勇者クラス、敵クラスで詳細を定義する
なぜクラスを定義するのか
上記のオブジェクト生成におけるクラス生成とほぼ同等の理由
クラスに基づいてインスタンスを生成できるようになる
クラスから生まれたインスタンスを入れる変数の型が利用できるようになる
車の部品から様々な車種を作るのと考えは一緒
クラス型とは
クラスを定義することで利用になる型のこと
クラス型変数とは
Java
は元々int,String
といったような型を標準で元々持っている
Hero型
を定義することでHero
という型が使えるようになる
このクラス型変数は識別をするために変数を用いる
例えばHeroクラス
で勇者を作り勇者が2人いたとした場合どちらがどの勇者か識別がつかなくなる
そのためクラス変数の型にインスタンスを代入し識別をするのが主な用途
クラスを利用する順番
1.クラスの変数を宣言
Average student ;
Averageクラス
の変数student
を宣言
この時点では変数宣言のみであり実体は存在しない
2.クラスの実体を生成
student = new Average ();
new演算子
を使用しAverageクラス
の実体を生成する
1,2を合わせて
Average student = new Average() ;
このように記述することで変数student
をAverageクラス
として使用することができる
この生成したクラスの実体をインスタンスという
メンバ
クラスを構成するフィールドとメソッドのことをクラスのメンバという
メンバへのアクセスは以下の記述でアクセスが可能
変数名.フィールド名
例としてAverageクラス
にmathフィールド
があるとする
student.math
アクセスしたフィールドは変数として扱うことができる
Average num = new Average();
num.math = 150;
num.science = 200;
System.out.println( "数学の平均点数:" + num.math);
System.out.println( "化学の平均点数:" + num.science); //出力:数学の平均点数:150 化学の平均点数:200
4.継承 ( extend )
別のクラスのメソッドが使えるようにすること
Heroクラス
を作った場合、次にさらに強いSuperHeroクラス
を作りたいとする
その際Heroクラス
内のメソッドを再びSuperHeroクラス
内に記述しなければならない
そこでHeroクラス
のメソッドを使えるようにすることを継承という
記述方法はクラス定義の先頭部分にextands
を記述
//AはBを継承する
public class A extands B {...}
オーバーライド
継承した先のSuperHeroクラス
で引き継いだメソッドを上書きすること
継承元のHeroクラス
内のattack()
というメソッドがある場合
新たに継承先のSuperHeroクラス
でattack()
を使用したい場合などに用いる
このようにSuperHeroクラス
の継承先で上書きすることで
継承して受け継いだものを変更することができる
厳密にいうとオーバーライド後の継承元のattack()
は消滅していない
呼び出しが届かないことから上書きされているように見えるだけである
superメソッド
子のインスタンスから親インスタンスへメソッドやフィールドがアクセスできる
オーバーライドしている場合は元々あったメソッドやフィールドをどうしても使いたい場合がある
そんな時に使用するメソッドがsuperメソッド
高度な継承
これまでの話をさらに抽象化し俯瞰で考えみると、
始めにHeroクラス
を作成し細かい設定を記述していた
だがHeroクラス
とは別に魔法使いのwizardクラス
や
回復がメインの僧侶クラス
といった多くのクラスが増えた場合に、
①クラスを作る
-
②クラス内にHPやnameのフィールドを作る
と作る度に定義をしなければならない
この手間を省くためHeroクラスに備わっていたものを全て持ち備えたCharacterクラス
という大元を作成し
中身は自由に書き換えてクラスを作ってくださいという思想が高度な継承と言える
高度な継承による不具合
高度な継承をするにあたり
攻撃attackの初期値はどうしようか?
といった問題が起こる
そもそも攻撃を書かなければいいという対策もできる
必要な場合にオーバーライドするよう記述すればいいが
①オーバーライドをうっかり書き忘れる
-
②本当は何も攻撃をしないクラスじゃないのか..?いや攻撃値をオーバーライドで書くべなのか..?
といったようにコードを書く上で懸念も生じる
そしてcharactarクラス
をnew
してしまうといった -
③意図しないnew
の可能性もある
未完成であるcharacterクラス
から実体を生成しては不完全のためよくない
不具合の解決
抽象メソッドとも言われるabstractメソッド
を利用する
public abstract void attack;
{}
カギカッコ無しの記述を用いる
こうすることで何をするか曖昧なメソッドと認識することができる
abstractクラス(抽象クラス)
abstractメソッド
があるクラスはabstractクラス
にしなければならない
よって曖昧なメソッドに所属するクラスは必ずabstractクラス
になる
このようなクラスを抽象クラスという
そして抽象クラスはnew
が禁止されているためエラーとなる
よって高度な継承による不具合③はabstarctクラス
にすることにより解決する
5.多様性
コンピュータにもざっくりとを教えるような考え方のこと
ヒトはある車を乗ったら別の車も乗れて運転できる
だがコンピュータは車それぞれを明確に別で考えてしまう
このヒトの考え方をコンピュータにも捉えるようにしたのが多様性
RPG
を題材としたコードを記述した場合、勇者を操作するためのHero
クラスと
魔法使いを操作するためのWizard
クラスを生成したとする
多様性(ざっくりと考える)を用いることでHero
とWizard
を同一に考えることができ、HP回復
もまとめてできる
多様性におけるメリット
人間が呼び出したものがそれぞれ独自のスタイルで呼び出されるため多様性と言われている
-
配列化が可能
ざっくりとした分類にされているため
Hero
であってもWizard
であっても同じざっくりとしたグループ化にすることが可能
そのためMain
でそれぞれ+=50
ずつ回復させたい場合
Hero A += 50
Wizard B += 50
といった面倒な記述をしなくても
c[0] = new Hero();
c[1] = new Wizar();
としfor文で+50ずつそれぞれ加算すれば簡略化した文が可能となる
-
それぞれの出力が可能
クラスごとに攻撃方法が異なるメソッドが存在した場合
それぞれ独自の攻撃方法が出力される
このような面からも多様性と名付けられている
要約すると、同一視してまとめて処理できることがメリットである
6.カプセル化
制限できるようにすること
人間がコードを記述するためミスやメソッドを間違って使ってしまう場合がある
そのために制限をかけることにより事前にバグを防げるのがカプセル化
あるクラスが外部から直接触られないようメソッドという殻(カプセル)で
フィールドが保護されているようなことからカプセル化とも言われている
privateを利用しメソッドを通して間接的にフィールドの処理を行うこと
private修飾子
外部からのアクセスを制限する修飾子
制限すると使い勝手が悪いためカプセル化を行い利便性を測る
制限レベル
制限レベルは4つあるがここでは
privateプライベート
-
publicパブリック
2つを理解する
他のクラスから変更されないようにするためにHPフィールド
をプライベート
にしたい場合
private int hp;
と記述する
そうすることで誤った値を使用される心配がなくなる
フィールドという限定的な場所
メソッドは処理が走った後は変更されることは無い
だがattack
といったフィールドは値が変化するものであり
制限箇所を狭めフィールドを保護することが重要とされる
フィールド
車で言う速度・メーカー
の部分
雛形を作成しているイメージ
前述したRPG
を題材としたコード内においてクラスがある場合、
HP
やMP
などがメソッド内で活躍するデータとして扱われる
これをフィールドと呼ばれる
例
public class Body{
String name;
double weigth;
}
String型
のneme
やdouble型
のweigth
それぞれフィールドになる
フィールドには実体がない
そのためインスタンス生成をしなければ利用することができない
new演算子
を使用する必要がある
フィールドにアクセスする場合
ドット演算子を使用する
変数名.フィールド名
参考文献
スッキリわかるJava入門 第3版
著者:中山清喬 と国本大悟 発行所:株式会社インプレス