オブジェクト指向についてHUNTER×HUNTERを使ってまとめてみた


はじめに


  • プログラミングを初めて一番最初にくる壁、オブジェクト指向について概念的なものをまとめてみた

  • 久々にHUNTER×HUNTER観たら、影響されてしまったので、ブログ書いてみた

  • 自分はプログラミング歴3ヶ月の初心者です。誤った理解があったり、コードも冗長になっているかもしれません。

  • その時はコメント頂ければ勉強になるので嬉しいです

  • 同じ初心者の方の参考になれば嬉しいです (→今回のブログの主目的)


簡単な概念

よく初心者向け記事でオブジェクト指向の説明をする時に「車」の記事が出るかと思います


  • クラス … 車の設計図

  • インスタンス … 設計図を元に具現化された車

  • プロパティ(属性) … 設計図に記されている車の情報

  • メソッド(操作) … 車への操作、処理。ドライブしたりとか

おそらくこんな感じかなと、自分はこの説明聞いて分かったような分からなかったような感じでした、、、そもそもプログラミグで車作ることないし。なので、イメージしやすいようにwebサービスでよくある「入力フォーム」で例えると


  • クラス … フォームの設計図。これがあるとみんな楽に簡単にフォームの機能を実装できる。そして誰が実装しても同じようなものが作れるので、汎用性が高い

  • インスタンス … クラスを元に実際に作られたフォーム。実際にフォームを作る時はクラスを元にそれぞれカスタマイズして作る。

  • プロパティ(属性) … クラスに記されているフォームの情報。サイズとか、色とか、ボタンとか

  • メソッド(操作) … 操作、処理。ボタンを押した時にどういう処理をするとか

厳密には違うかもですが、およそこんな感じかなと思います。


Pythonでの実装

# クラスの宣言

class Hunter:
def __init__(self, name, mind_type, ability_point):
self.name = name
self.mind_type = mind_type
self.ability_point = ability_point

# 先程のクラスからインスタンスを宣言
gon = Hunter('gon', '強化系', 100)
killua = Hunter('kila', '変化系', 130)
kurapika = Hunter('kurapika', '具現化系', 120)

クラス(設計図)を元にいくつかのインスタンスを具現化しました。この具現化されたインスタンスのプロパティを参照することもできます。

# [out] ゴンの念タイプ:  強化系

print('ゴンの念タイプ: ', gon.mind_type)
# [out] キルアの念タイプ: 変化系
print('キルアの念タイプ: ', killua.mind_type)
# [out] クラピカの念タイプ: 具現化系
print('クラピカの念タイプ: ', kurapika.mind_type)

先程のクラスは簡単なプロパティを持っているだけでしたが、これにメソッドを追加してみたいと思います。

class Hunter:

def __init__(self, name, mind_type, ability_point):
self.name = name
self.mind_type = mind_type
self.ability_point = ability_point

# 新しいメソッド(kakusei)
def kakusei(self, strength, change_mind=None):
self.ability_point += strength
if change_mind != None:
self.mind_type = change_mind

メソッドを定義しておくことで、以下簡単なコードで処理できます。

kurapika = Hunter('kurapika', '具現化系', 120)

# クラピカのability_pointをアップ and mind_typeをチェンジ
kurapika.kakusei(300, '特質系')

# [out] クラピカのアビリティポイント: 420 クラピカの念タイプ: 特質系
print('クラピカのアビリティポイント: ', kurapika.ability_point,
'クラピカの念タイプ: ', kurapika.mind_type)

# メソッドを三回ループ
for _ in range(3):
kurapika.kakusei(100)

# [out] クラピカのアビリティポイント: 720 クラピカの念タイプ: 特質系
print('クラピカのアビリティポイント: ', kurapika.ability_point,
'クラピカの念タイプ: ', kurapika.mind_type)

二つ目のメソッドを追加してみます

class Hunter:

def __init__(self, name, mind_type, ability_point):
self.name = name
self.mind_type = mind_type
self.ability_point = ability_point

def kakusei(self, strength, change_mind=None):
self.ability_point += strength
self.mind_type = change_mind

# アビリティポイントをそれぞれの念能力に振り分けるメソッド(point_sorting)
# self以下、「強化系」、「放出系」、「変化系」、「操作系」、「具現化系」、「特質系」
def point_sorting(self,
enhancer=0,
emitter=0,
transmuter=0,
manipulator=0,
conjurer=0,
specialist=0):

total = \
enhancer + \
emitter + \
transmuter + \
manipulator + \
conjurer + \
specialist

if 0.00001 < total - 1 or total - 1< -0.00001:
print('アビリティポイントの振り分け割合を合計で1にしてください')

else:
enh = enhancer * self.ability_point
emi = emitter * self.ability_point
tra = transmuter * self.ability_point
man = manipulator * self.ability_point
con = conjurer * self.ability_point
spe = specialist * self.ability_point

if self.mind_type == '強化系':
enh *= 5
emi *= 2
tra *= 2
elif self.mind_type == '放出系':
emi *= 5
man *= 2
enh *= 2
elif self.mind_type == '変化系':
tra *= 5
enh *= 2
con *= 2
elif self.mind_type == '操作系':
man *= 5
spe *= 2
emi *= 2
elif self.mind_type == '具現化系':
con *= 5
tra *= 2
spe *= 2
elif self.mind_type == '特質系':
spe *= 5
man *= 2
con *= 2

ability_sort = {
'強化系': enh,
'放出系': emi,
'変化系': tra,
'操作系': man,
'具現化系': con,
'特質系': spe
}

return ability_sort

定義されたメソッドは簡単に実行できます

# インスタンスを宣言

gon = Hunter('gon', '強化系', 100)
kasutoro = Hunter('kasutoro', '強化系', 100)

'''
[out] ゴンのpoint_sorting:
{'強化系': 350.0, '放出系': 40.0, '変化系': 20.0,
'操作系': 0, '具現化系': 0, '特質系': 0}
'''

print('ゴンのpoint_sorting: ', gon.point_sorting(0.7, 0.2, 0.1))

'''
[out] カストロのpoint_sorting:
{'強化系': 0, '放出系': 60.0, '変化系': 0,
'操作系': 30.0, '具現化系': 40.0, '特質系': 0}
'''

print('カストロのpoint_sorting: ', kasutoro.point_sorting(0, 0.3, 0, 0.3, 0.4))

仮に同じアビリティポイントだとしてもその振り分け方を誤るとメモリの無駄遣いになるということを表現しました。このように色々な処理をする時に予めオブジェクトを作っておくと、簡単なコードでかつ誰が見ても分かりやすく実装できます。