0
0

【Java】オブジェクト指向

Last updated at Posted at 2023-06-14

0.はじめに

Javaを大学で学んでおります。
概念や特徴を以下の文類に分けてまとめました。

関連学習

【Java】用語
【Java】メソッド・型
【Java】オブジェクト指向
【Java】インスタンス・コンストラクタ
【Java】例外処理
【Java】注意点・ルール
【Java】コードの記述向上にむけて(個人用memo)

1.3大構成

オブジェクト指向は以下3点による構成がされる

  • 継承
  • 多様性
  • カプセル化

2.オブジェクト指向について

これまで学んだ文法や計算方法というのは車でいう設計書のようなもの
オブジェクト指向とはどうすれば車を作り出すことができるのかという考え方に則る

ゴールから逆算して考えるため、どうすれば正解にたどりつけるか
数字の1019を使用する際は "足し算を使えばいい"といった
正解を導き出すための思考が必要

そもそもオブジェクトとは

クラスを実体化したものや仮想世界で活動するモノの総称
データと手続きを一体化(カプセル化)して定義利用するものなど

フィールドを参照しインスタンス(実体)を生成した場合
そのインスタンスそのもののことや、配列における本体のことを
オブジェクトと呼ばれる

メリット

現実世界のモノを仮想世界内でも忠実に再現することが可能
人間が内容を把握しやすくし開発ができるためラクをすることができる

手続き型の違い

手続きは一行ずつそれぞれ書いていき、何をしようかと試行錯誤を繰り返すが
オブジェクト指向は必要なものを抽出し構築をしていく
その必要な要素それぞれを連携させ設計図を書いていく
リアルな設計処理実行をコード内でも実現すればいいという考え方

オブジェクト指向と非オブジェクト指向

明確な思想に基づいてクラスが設計される
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() ;	

このように記述することで変数studentAverageクラスとして使用することができる
この生成したクラスの実体をインスタンスという

メンバ

クラスを構成するフィールドとメソッドのことをクラスのメンバという
メンバへのアクセスは以下の記述でアクセスが可能

変数名.フィールド名

例として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クラスを生成したとする
多様性(ざっくりと考える)を用いることでHeroWizardを同一に考えることができ、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を題材としたコード内においてクラスがある場合、
HPMPなどがメソッド内で活躍するデータとして扱われる
これをフィールドと呼ばれる

public class Body{
    String name;
    double weigth;
}

String型nemedouble型weigthそれぞれフィールドになる

フィールドには実体がない

そのためインスタンス生成をしなければ利用することができない
new演算子を使用する必要がある

フィールドにアクセスする場合

ドット演算子を使用する

変数名.フィールド名

参考文献

スッキリわかるJava入門 第3版
著者:中山清喬 と国本大悟 発行所:株式会社インプレス

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0