こちらはITRC Advent Calendar 2019 18日目の記事です。
前回の記事
次回 : ??
経緯
よ〜し!Rustのプログラムかくぞ〜!
ん?ここなんでエラー出てるんだろ?
ん?なおらんぞ?
ここを直せば!
直った?いや、エラーが増えた!?
やばい日付かわった。。
ん?先週と同じだって..?
知らないな〜〜〜〜なんの事かな〜〜〜〜??????
みなさんこんにちは! @saba383810です。rustで他のことをやろうとも思ったのですがエラーや使いたいクレートがうまくインストールできないなどの事件があったので今回はゆるしてちょ。そこでなにを書くか考えていたところ授業でちょうどオブジェクト指向について触れていてオブジェクト指向について理解し始めたのでメモ程度に記事を書きたいと思います。
今回はpythonのサンプルコードをみながら説明していこうと思うのですが、pythonのオブジェクト指向は言語使用が緩いのもあり完璧ではないのです。でもだからこそpythonはオブジェクト指向に慣れるために向いてるのではと思います。初学者ながらがんばってまとめてみたのでどうぞ!
注意 : 間違った知識がある場合があるので予めご了承ください。
オブジェクト指向とは
オブジェクト指向についてネットで調べると
- モノとして考えると簡単
- 車の例
- オブジェクトはモノ
- クラスは分類
などと様々な人が初学者にわかりやすく説明しようと努力しています。どれも間違っているわけではないのですがあまりピンときませんよね。そんな中私はオブジェクト指向は考えるものではなく、自然と理解してくるものだと思っています。このことを踏まえて今回は堅苦しい説明は抜きにしてpythonのソースコードをみながら自然に学んで行けたらいいなと思います。
ゼロから始める「オブジェクト指向」ってね!
クラス
今回はクラスについて詳しく見ていきましょう。
クラスは効率よくプログラムしていくためのしくみです。クラスがやることそれは
「データ(変数てきな)」と「処理(関数てきな)」をまとめる
それだけですかんたんにみえるかな?
class クラス名:
def メソッド名(self,引数):
self.変数 = 値
return 式
クラスはこのように書いていきます。順番にみていきましょう!
##クラスの定義
class Person:#クラスの定義(関数とおんなじ感じにインデントするよ!)
#クラスの内容
クラスの定義はかんたんでclass
という修飾をつけて自分の好きな名前で宣言するだけ!
ここだけの話、クラスと関数の区別を作るために
クラスの最初の文字 :大文字 例) class Person:
関数の最初の文字 :小文字 例) def person:
というプログラムをわかりやすくする命名条件があったりします。
##メソッドと属性
class Person:#クラスの定義
def getName(self):#ここがめそっどだよ!
return self.name #ここがデータの属性だよ!
def getAge(self):#ここもめそっど!
return self.age
メソッドとはクラス経由でしか呼び出せない関数みたいなものって考えるとわかりやすいと思う。ここに、あとで呼び出したい処理を記述しておきましょう。
データの属性ってあるけどわかりづらいよね。実際は変数みたいにつかうのでそういう感覚で多分大丈夫!
インスタンス化
クラスは宣言しただけでは使用できません。
訂正 : ***宣言しただけでも関数として使用でき、***インスタンス化することで、個別の処理(メソッド)やデータを持てるようになるようです。
そこでクラスを外で使用できるようにする作業が必要です。それがインスタンス化なのです。
person = Person() #インスタンス化
インスタンス化されたperson
はインスタンスとなります。
person
にはまだなんの値も入っていません。
そこで
person.name = "さば"
person.age = 19
このように入力することで代入することができます。
代入した値を出すためには先ほど作成したメソッドを使います。
person = Person() #インスタンス化
perrson.name = "さば" #データの属性を付与
person.age = 19 #データの属性を付与
playerName = person.getName() #Person()で定義したメソッドを使用
PlayerAge = person.getAge() #Person()で定義したメソッドを使用
インスタンス化したことでperson ≒ Person()
なのでperson.getName()
でPersonの中のメソッドにアクセスすることができます。
コンストラクタ
先ほどはデータの属性を後から付与していたと思います。しかしそれではオブジェクト指向の良さをあまり引き出せていません。ここではインスタンス化するときにデータの属性を付与するコンストラクタについて説明します。
コンストラクタとはインスタンス化されたときに一度だけ実行される処理のことです。簡単に言えば初期化です。
訂正 : __init__
メソッドは初期化メソッドで間違いがないのですがコンストラクタにはそれ以外にも__new__
メソッドというものあるので「コンストラクタ=__init__
メソッド」は間違っているそうです。後から呼び出すことも一応は可能とのことです。、
class Person:
def __init__(self,name,age):# コレがコンストラクタ
self.name = name
self.age = age
person = Person("さば",19) #インスタンス化するときに引数がある。
__init__
と記述された文はインスタンス化されたときに一度だけ引数を持って実行できます。
この時点では「後から代入してもよくね?」と感じると思いますがこの後説明するカプセル化と使用すると効果を引き出せるので今はふーんと聞き流してください。
カプセル化
pythonは言語仕様が緩いと最初に話したのですが、そのせいで後からクラスの属性にアクセスしマイナスの値や異なる値を代入できてしまいます。
pythonのクラスを定義する際には、
アクセスを制限したい属性の名前を
アンダースコア1つ(_)から始まる名前とする
という方法が、慣習として行われているそうです。
class Person():
def__init__(self,name,age):
self._name = name # <-アンダースコアが1個ついている
...
それでも間違えて***アンダースコア(_)***を書いてしまい書き換えしてしまうということもあると思います。pythonでは強制的に書き換えができないようにすることができます。そのためには
属性の名前をアンダースコア2つ(__)から始まる名前にする
という方法で記述します
class Person():
def__init__(self,name,age):
self.__name = name # <-アンダースコアが2個ついている
...
このように外からクラス内の属性がカプセルに入っているかのように中が見えないようにすること(隠蔽すること)をカプセル化といいます。
追記 : 隠蔽することだけがカプセル化ではなく、複雑な処理やプロトコルを隠して使いやすくするのもカプセル化の役割らしいです。
さらに一般的には、アンダースコアを二つ付けるやり方は、サブクラスと名前が衝突した時のみ使用した方が良いらしいです。あまり推奨されないやり方なんですね。。
#まとめ
疲れたので今回はここまでにします。
今回の内容を簡単にまとめると
- クラスの定義は簡単
- クラスの中には属性(変数のようなもの)とメソッド(関数のようなもの)がある
- インスタンス化はクラス外でしようできるようにする。
- コンストラクタとカプセル化で安全なプログラムを書く
です。
簡単に書くために言葉を選んで書いてみたのですがどうでしたか?
間違っているところがあったら遠慮せずにコメントしていただけると嬉しいです。
追記 : 間違っている知識があり多々訂正させていただきました。
#参考資料