12.効率的にクラスを活用する方法
※無料で読めます
プログラミング未経験でも大丈夫?
オブジェクト指向って何?
オブジェクト指向分からない…
継承とは?
カプセル化とは?
多態性(ポリモーフィズム)とは?
初めてjava を学習してみようという方/javaでコーディングできるけどやり方がいまいちわからない方に向けた記事です。
アジェンダ
それでは、いつものように私なりの言葉で、読んでいて眠くなることがないように、タイトルなども工夫していきます。
今回のゴール
・継承が使いこなせる
・カプセル化がそこそこ使える
・多態性が使いこなせる
本記事は、クラスとアクセス修飾子のことを知っていることを前提としてまとめます。
1. 「知」は「力」のためにある
さっそくですが、「オブジェクト指向」という言葉の説明はしません。期待して読み始めようと思った方、申し訳ありません。
❌「オブジェクト指向とは何かを理解する」
✅「こういう風にやれば良いのか。と使っていたものが、実はオブジェクト指向だった」
これがあるべき姿、やるべきことではないかと思うからです。
2. 振り返ることで初めて気づくもの
まずはクラスでできること、「クラスの可能性」を確認しましょう。
1. データの保管ができる
2. 特定の処理をまとめることができる
「処理をまとめる」のは、メソッド(method)のことです。
「データの保管ができる」のは、フィールド(field)のことです。
この二つによって、クラスで色々な表現をすることができます。
モノであっても、処理であっても、何でもです。
3. 少し先の未来が見えれば楽ができる
Q.「すべての要素や使える処理が同じ」クラスがあるとします。
あなたはどのようにコーディングをしますか?
A. ❌ コピペします!
⭕継承の選択肢が取れるかを考えます。
実際にはクラスをコピペして、同じものをもう一つ作る方が短期的に見ると早いです(「Ctrl + C」⇒「Ctrl + V」とファイル名変更だけですから・・)
結果的にそうなってしまう場合もありますが、別の方法を知っていると長期的に見て修正する時間が少なく済んだり、コーディングでもやりやすくなる可能性があります。
その方法が、「継承」です。
extends をclass に使います。
例えば、学校の生徒とクラスを"class"で表現してみましょう。
public class Student {
public String name;
}
import java.util.ArrayList;
public class GradeClass {
public int gradeNumber;
public int classNumber;
public ArrayList<Student> students = new ArrayList<>();
}
クラス委員長が必要になりました。それを表現してみましょう。
public class ClassPresident extends Student {
}
ClassPresident は、 Student の全てを受け継ぐために利用します。
メソッドも、フィールドも全てです。
ちなみに。
この継承というものは、一つしか指定できないので注意してくださいね。
4. 其方は何者か?
継承によって、もう一つできることが増えます。
それは、子クラスを親クラスとしても扱えるということです。
全てを受け継いでいるということは、
「ClassPresident は Student でもある」ともいえますね。
// ClassPresident student = new ClassPresident();
Student student = new ClassPresident();
このように型の定義をすることもできるわけです。
ということは、下記ができます。
GradeClass fifthOne = new GradeClass();
fifthOne.students.add(new Student());
fifthOne.students.add(new ClassPresident());
この使い方のことを、「ポリモーフィズム」と言います。日本語でOKなら、「多態性」という呼び方でも同じ意味です。
難しく考える必要はありません。
「親クラスの型で扱う」というだけです。
5. 俯瞰して見れたならば何でも対応できる
ちなみに。
この継承というものは、一つしか指定できないので注意してくださいね。
多態性。つまり、インスタンスを親の型と見做して扱うようにしたい場合、この制約が実装の可能性を狭める可能性があります。
例えば、船を「人を運べる乗り物」の一つとして扱いたかったり、「荷物を運べる乗り物」の一つとして扱いたかったり・・。
「船」として扱うと、バスや飛行機が扱えなかったり。
別々の変数としてまとめると、同じ処理をコーディングする必要が出て、あまりシンプルな形にはなりません。
そんな時に使えるのが、「インターフェース」です。
interface を class の代わりに使い、
implements を class に使います。
public interface CarriablePeople {
/**
* @param driver 運転する人
* @param persons 乗る人
* @return 走行距離
*/
int drive(Driver driver, Person... persons);
}
public interface CarriableBaggages {
/*
* @param baggages 荷物
*/
void carry(Baggage... baggages);
}
public class Ship implements CarriablePeople, CarriableBaggages {
@Override
public int drive(Driver driver, Person... persons) {
}
@Override
public void carry(Baggage... baggages) {
}
}
6. 魔の手に触れられぬよう、秘匿し隠蔽せよ
もう一つは既にやっていることですが、アクセス修飾子のことです。
・どこでもOK! ⇒ public
・関連するやつと同じ場所にいるならOK! ⇒ protected
・同じ場所にいるならOK! ⇒ 何も書かない(package private と言う)
・このクラス内しかダメ。隠れてる。 ⇒ private
クラスの特徴として、「データの保管ができる」というものがありましたね。この保管しているデータへのアクセスを制御することも大事です。
このことを、「カブセル化」と言います。
さいごに
「継承」と「インターフェース」が使えるようになりました。
あとは、どういう風に実装していくかだけです。
その工夫の仕方の一つが、「オブジェクト指向」なのです。
簡潔に言うと、
モノをクラスとして表現していくことであり、
付け替えたり共通的なものを抽象化していくことです。
オブジェクト指向には残念ながら、答えがありません。
プロジェクトに合ったコーディングをするのが大事です。
だからこそ、システムエンジニアは頭を悩ませながら仕事をするのです。
次回、「想定しない状態になった時にどうするか」に関してまとめたいと思いますので、よろしければご覧になってください。
ちなみに…。
ここまで触れてきた工夫をクラスに落とし込むとこうなるでしょうか。
※ 正解ではないかもしれませんが、参考までに。
public class Student {
private String name;
public Student(String studentName) {
this.name = studentName;
}
public String getName() {
return this.name;
}
}
import java.util.ArrayList;
import java.util.List;
public class GradeClass {
private int gradeNumber;
private int classNumber;
private List<Student> students = new ArrayList<>();
public void addStudent(Student student) {
this.students.add(student);
}
void setGrade(int gradeNum, int classNum) {
this.gradeNumber = gradeNum;
this.classNumber = classNum;
}
public int getGrade() {
return this.gradeNumber;
}
public int getClassNum() {
return this.classNumber;
}
}
有料パートに関して
・今回の記事のまとめを書いています
※必須ではないけれど知っておいた方が良い知識も添えています
・具体的な方法と共に詳細説明をしています
ここから先は
¥ 300
いただいたサポートは、今後の創作活動に役立てさせていただきます。