参考
最近なぜシリーズにはまっている。
わかりやすくて大変良いです。 www.nikkeibp.co.jp
オブジェクト指向の3大要素
オブジェクト指向はプログラムを簡単にわかりやすく作るためのもの。
カプセル化(クラス)
まとめて隠してたくさん作る。
クラスの目的は整理整頓。
- まとめる:関連の強いメソッドや変数を1つのクラスにまとめて整理する。
- 隠す:privateなどで隠して影響範囲を限定する。
- たくさん作る:インタンスとして大量生産。
1クラスにごちゃまぜにするとわかりにくい。
public class Gotyamaze { private String humanName; private int accountNumber; private int humanAge; private String accountType; }
分けるとわかりやすいよね。
class Human { private String humanName; private int humanAge; } class Account { private int accountNumber; private String accountType; }
ポリモーフィズム(多態性)
メソッドの呼び出し方を共通化する。
異なる処理を同じ方法で呼び出せる。
public abstract class Animal { public abstract void cry(); }
public class Cat extends Animal{ @Override public void cry() { System.out.println("にゃーん"); } }
public class Dog extends Animal{ @Override public void cry() { System.out.println("ワンワン!"); } }
public class Main { public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ Animal cat = new Cat(); Animal dog = new Dog(); cat.cry(); // にゃーん dog.cry(); // ワンワン! } }
継承
クラスの継承。
継承の目的は重複を排除すること。
重複部分はスーパークラスに書く。
固有部分はサブクラスに書く。
public class Person { private int age; private String name; }
public class Employee extends Person { private String CompanyName; private String CompnayAddress; }
public class Student extends Person { private String SchoolName; private String SchoolAddress; }
オブジェクト指向以前はどうだったのか
本当の最初は1つのファイルにベタ書きしていた。
そして、サブルーチン(関数)が誕生した。
その後にサブルーチンの独立性を高めるために、ローカル変数と値渡しが生まれた。
あと、昔の言語には条件分岐(if)と繰り返し(for)が書けなかった?
あやふただけど、昔のCOBOLではif文やfor文を素直に書けなかったらしい。
代わりにGOTO文なるものを書いていたらしいが、これがコードの難読化の原因になっていた。
メモリに関する話
なぜ型宣言するのか
- メモリ領域確保
- コンパイルエラー用
静的領域・ヒープ領域・スタック領域
- 静的領域:プログラム開始時に確保、終了まで固定。1つだけ。static/グローバル変数/コード情報などが入る。
- ヒープ領域:プログラム実行時に動的に確保するメモリ領域。あらかじめ1つ確保しておく。 必要になったらヒープ領域が割り当てられ、不要になったら削除される。インスタンスが入る。
- スタック領域:メソッド制御のためのメモリ領域。スレッドごとに1つ。メソッドの引数/ローカル変数/戻り先などの情報が入る。
閃いた!
staticメソッドが非static(インスタンス)を参照できない理由が!
静的領域は最初にメモリ領域が確保される。
対してインスタンスは必要に応じてメモリ領域が割り当てられる。
だから、staticメソッドからインスタンスを参照しようにも、まだインスタンスが存在しないから。
ガベージコレクションの対象となる条件
静的領域とスタック領域から辿れないインスタンスが対象。
インスタンス同士で循環参照していても、静的領域とスタック領域から辿れなければガベージされる。
用語:スレッドとプロセス
どちらもプログラムの実行単位。
プロセスのほうが大きい単位。
スレッドの集まりがプロセス。
スレッド<プロセス
用語:参照とポインタ
Javaで言うところの参照ってポインタと同じ意味なんだって。
知らなかったわあ。
使ってみたいUML図
クラス図
クラスの仕様とクラス同士の関連。
ソース理解のために書いてみた。すごくいい。
シーケンス図
インスタンス間の処理の流れを時系列で表現。
アクティビティ図
役割ごとに分けた処理の流れを表現。
頭の整理に良い。
自分ハマったときに処理の流れを細かく分解するのだけど、その時にこれを使うと良さそう。
あと業務分析にも使えそう。
ユースケース図
棒人間。
システムの機能と利用者の関係を表現。
これも頭の整理、業務分析に使えそう。
主に役割分担に良さげ。
関数型言語
存在は知っていたけど、どんなものかは初めて知った。
なんか楽しそうやなあ、使ってみたいわあ。
ちなみに副作用という話が出てきて、副作用というのは外部入出力のこと。
つまりI/Oを使用せず、CPUとメモリだけで処理が完了するということなのかしら。
低レイヤを勉強するとこんな感じで知識が活きるんやなあと実感。
まとめ
オブジェクト指向はプログラムを簡単に作るためのもの。
3大要素。
・カプセル化(クラス)
整理整頓が目的。
関連の強いメソッドや変数をひとまとめにする。
private/protectedなどで影響範囲を限定する。
現実でいうと収納。キッチンの収納にはキッチン用品、玄関の収納には靴、というように関連の強いものを収納する。
メリットは人間にとってわかりやすく、修正しやすいプログラムを書ける。
メソッドの呼び出し側を共通化する仕組み。
呼び出し方法は同じでも異なる処理が呼び出せる。
現実でいうと「Aさんアレやっといてー」みたいな。
有能なAさんはアレが何かを的確に判断し、その時々で必要なアレを処理する。
メリットは修正が簡易になること。
例えば呼び出される側(メソッド)を増やしても、呼び出し側を修正する必要がない。
・継承
クラスの重複を排除する仕組み。
サブクラスはスーパークラスの定義を含む。
サブクラスにはスーパークラスにはない固有の定義を書ける。
現実でいうと出産?人間の子は手足や頭、遺伝子を親から継承している。
しかし、子供固有の性格や身体的特徴を持つ。
ちょっとこの例えは無理があるかw
メリットは同じコードを何度も書かなくて済むこと。
・UML図
個人的に使いそうなのは
- クラス図
- シーケンス図
- アクティビティ図
- ユースケース図
プログラミングだけでなく、業務分析や頭の整理にも使えそう。