オブジェクト指向
あくまで一つの理解の形として。
オブジェクト指向とは、ではなく、なぜオブジェクト指向言語なのか。
言わずとだが、理解に変化があれば随時書き直す。
プログラムはアルゴリズムとデータ構造からなる。
データ構造といえばスタックやキューなどの「データを保持する手法」、アルゴリズムといえばリニアサーチやバイナリサーチなどの「データを処理するための方法」。平たく言えば、①「データ」の管理方法と②「処理手法」で良いと思う。
これを③「制御構造」で繋ぎ合わせて機能を実現する。
これを②や③に着眼点をおいてまとめ上げる手法が構造化プログラミング(structured programming)。簡単な制御構造を多段階に組み合わせて②や③を実現することで、プログラム・パーツの流用性を良くし、大きな処理をパーツの組み合わせで簡単に組み上げることを利点とする。
オブジェクト指向とは、その名の通りオブジェクト(モノ)の単位でプログラムを構成する考え方のこと。すべてのオブジェクトは固有情報をもって独立していて、オブジェクトの中にアルゴリズム(処理)とデータ構造が存在する。プログラムの骨子ではこのオブジェクトをどのように扱うかを記述する(メッセージを送る)。
ちなみにリストは型自体にプッシュ・ポップなどのデータ構造を扱うメソッドがあり、ソートなどの処理手法も持っていて、そう言った理論の実現方法を知らなくて良く、使うことに専念できる。人気のある言語を選ぶと、こういった機能がどんどん拡張される(ライブラリとして提供される)メリットがある。
(下記は比較するための例なので、あえて古典的なことをしている。)
リストを整列するプログラム
""" 前準備 """バブルソート関数を定義する:装置X
""" データ """
10~19の数字のかかれた10個のボールをランダムに並べる:リストA
20~29の数字のかかれた10個のボールをランダムに並べる:リストB
""" 処置 """
リストAを装置Xに入れて戻り値をリストAに入れる(取り出す)
リストBを装置Xにいれて戻り値をリストBに入れる(取り出す)
リストを整列するプログラム(オブジェクト指向)
""" 前準備 """
クラスPを定義する。
・クラスPはリストQを保持する
・リストQは外から設定することができる
・リストQは外から参照することができる
・リストQをバブルソートさせる命令を外から与えることができる
""" データ """
クラスPからオブジェクトC、Dを作る(インスタンシェート)。
オブジェクトCに10~19の数字のかかれたボールを入れる
オブジェクトDに20~29の数字のかかれたボールを入れる
""" 処理 """
オブジェクトCにバブルソートするよう命令する
オブジェクトDにバブルソートするよう命令する
オブジェクトCのQを参照する
オブジェクトDのQを参照する
前者も後者もやっていることは同じである。 前者はデータ(リストA、リストB)と処理(装置X)という形でプログラムの構成要素を整理している。 後者はオブジェクト(リストと処理を内部に持つ)という形でプログラムの構成要素を整理している。
プログラムを書いていると、規模か膨らむにつれて変数の数が増え、その変数がどの処理に関係するものなのかがわかりにくくなっていくことがあるかと思う。関数も同様で、同じ関数をいろいろな関数で多重に呼び出すことでプログラム資産の流用性を良くすることがあると思うが、反面、一部の関数を変更すると呼び出し側の関数に影響してしまったり、まったく別の目的で同じ関数を使うことで用途と関数名が微妙にずれて見通しのわるいソースになったりしてしまうことがあると思う。
オブジェクト指向を使う理由は、変数や関数を使いまわすのではなくオブジェクト専用にすることで、プログラムの見通しをよくするためだと思う。
オブジェクトのもとになる型のことをクラスと呼ぶ。クラスは通常、変数と関数をもっている。これを使うには<インスタンス>.<変数や関数>のように指定する。Cの構造体に似ている。C++ではまさに構造体のメンバに関数が追加されたイメージで、変数をメンバ変数、関数をメンバ関数と呼ぶ。pythonではインスタンス変数、メソッドと呼び、細かい違いはあるが概ね同じ概念である。 HDLも似た概念になっていて、Verilog-HDLのモジュール(クラス)とインスタンス(オブジェクト)の関係に似ている。HDLでは同じ設計図(モジュール)を一つの回路に複数構成する場合、同じモジュールを別のインスタンス名でインスタンシエーションする。多くの(?)オブジェクト指向のプログラミング言語ではインスタンス変数にアクセスするのにメソッドを使う作法になっている(pythonは直接アクセス出来る)のに対し、HDLはここが逆のイメージで、ファンクションを動かすために変数をスイッチのように設定する(結果はI/Oに現れたり変数(レジスタ)に格納されたりする)。変数には固有のアドレスをオブジェクトの外側で定義することで、どのインスタンスの変数を活性化するかを区別している。
カプセル化、継承、ポリモーフィズムはオブジェクト指向の基本概念なので、pythonでも他の言語と同様である。(HDLを対比に挙げたが、こちらは正確にはオブジェクト指向というわけではないので、継承、ポリモーフィズムの”手法”はない。カプセル化はあるといえばある。概念として実装することはもちろん可能。SystemVerilogは別として。)
0 件のコメント:
コメントを投稿