📚

Python-クラスの継承(基礎)

に公開

Pythonのクラスの継承について学習する

こんにちは!わいわわです。
AIとPythonの学習を進めています。
プログラミング学習サービスの「Progate」さんの
pythonの最終カリキュラムを終了し、クラスの継承について学習しましたので、
今回アウトプットとしてまとめていきます!

最終的にできるアプリ

今回クラスの継承を学習するにあたり完成したアプリです。
ユーザーからフードとドリンクの番号を入力してもらい、
その購入セット数を入力してもらうと合計金額が算出されます。

script.py
from food import Food
from drink import Drink

food1 = Food('サンドイッチ', 500, 330)
food2 = Food('チョコケーキ', 400, 450)
food3 = Food('シュークリーム', 200, 180)

foods = [food1, food2, food3]

drink1 = Drink('コーヒー', 300, 180)
drink2 = Drink('オレンジジュース', 200, 350)
drink3 = Drink('エスプレッソ', 300, 30)

drinks = [drink1, drink2, drink3]

print('食べ物メニュー')
index = 0
for food in foods:
    print(str(index) + '. ' + food.info())
    index += 1

print('飲み物メニュー')
index = 0
for drink in drinks:
    print(str(index) + '. ' + drink.info())
    index += 1

print('--------------------')

food_order = int(input('食べ物の番号を選択してください: '))
selected_food = foods[food_order]

drink_order = int(input('飲み物の番号を選択してください: '))
selected_drink = drinks[drink_order]

count = int(input('何セット買いますか?(3つ以上で1割引): '))

result = selected_food.get_total_price(count) + selected_drink.get_total_price(count)

print('合計は' + str(result) + '円です')

また、クラスごとにモジュールを分けて作成しており、
下記3つのモジュールをアコーディオンで記載します。
menu_item food drink

menu_item.py
menu_item.py
class MenuItem:
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def info(self):
        return self.name + ': ¥' + str(self.price)

    def get_total_price(self, count):
        total_price = self.price * count

        if count >= 3:
            total_price *= 0.9

        return round(total_price)
food.py
food.py
from menu_item import MenuItem

class Food(MenuItem):
    def __init__(self, name, price, calorie):
        super().__init__(name, price)
        self.calorie = calorie
    
    def info(self):
        return self.name + ': ¥' + str(self.price) + ' (' + str(self.calorie) + 'kcal)'
    
    def calorie_info(self):
        print(str(self.calorie) + 'kcalです')
drink.py
drink.py
from menu_item import MenuItem

class Drink(MenuItem):
    def __init__(self, name, price, amount):
        super().__init__(name, price)
        self.amount = amount

    def info(self):
        return self.name + ': ¥' + str(self.price) + ' (' + str(self.amount) + 'mL)'

クラスの継承

今回、初めに「menu_item」クラスを作成し、
そのあとでmenu_itemクラスを利用して「food」「drink」クラスを作成しています
これを継承といいます。

foodとdrinkクラスはname,priceが共通しているため、
この2つをmenu_itemクラスで定義し、
それぞれのモジュールで継承したのち、追加で
foodは「calorie」、drinkは「amount」を作成しています。
これを行うことによって、書く量が減りますね!

menu_itemを親クラス、親クラスから継承した2つを子クラスと呼び、
子クラスは親クラスのメソッドを使えます。
そのため、def info(self)get_total_price(self, count)
foodクラス、drinkクラスでも使えます。
使えたうえで子クラス(food)は専用のcalorie_info(self)を作成することで
その子クラスだけに欲しいメソッドを作成することもできます。

また、親クラスと同じ名前のメソッドを子クラスでも再度定義し、上書きができます。
これをオーバーライドといいます!

super()とinit

init、こちらはインスタンスが作られる際に実行されるメソッドです。
こちらも子クラスは親クラスのものを受け継いでいますが、改良ができます!
・親クラス

menu_item.py
class MenuItem:
    def __init__(self, name, price):
        self.name = name
        self.price = price

・子クラス

food.py
from menu_item import MenuItem

class Food(MenuItem):
    def __init__(self, name, price, calorie):
        super().__init__(name, price)
        self.calorie = calorie

super()メソッド
オーバーライドしたメソッドの中で呼び出すことで親クラスを呼び出すことができます。
親クラスにはself.name=nameself.price=oriceがありますが、
この2つは子クラスも記述しなければなりません。

そこで記述量を減らすためにsuper()メソッドを使い、親クラスの記述を持ってきています。

子クラスは「親クラス内に定義されているメソッド」
と「独自に定義したメソッド」の両方が使えるということですね!

今回は継承とsuper()メソッドにより、記述量をすっきりさせた
pythonのプログラムを作成しました!

機能のまとめ

1.foodインスタンスを3つ作成し、foods配列に格納(drinkも同じく)
2.配列から1つずつ取り出し、メニューの数だけ番号とデータを表示
3.食べ物と飲み物の番号、また購入セット数を入力させる
4.合計金額を算出
以上がこのプログラムでできることでした!

所感

今回はprogateさんのカリキュラムであるpythonのクラスの継承を学習しました。
今回はインスタンスに入っている情報が3つでしたが、もっともっと情報が多くなると
学習した継承やsuper()、オーバーライドなどの真骨頂になるのかなと感じました!
これでprogateさんのpythonは受け終わりました!
これからよりもっと深くpythonの勉強を進めていきます!

Discussion