[Python]親クラスで子クラスのメンバを使用する。

コード

 coding=utf-8

from abc import ABCMeta, abstractmethod

class Parent(object):
    
    @abstractmethod
    def hoge(self):
        print(self.name)

    @abstractmethod
    def fuga(self):
        print(self.age)

    @abstractmethod
    def fuga2(self, age):
        print(age)

class Child(Parent):

    def __init__(self):
        self.name='nekonisi'
        self.__age='26'

    def hoge(self):
        super().hoge()

    def fuga(self):
        super().fuga() #error

    def fuga2(self):
        super().fuga2(self.__age)

if __name__ == '__main__':
    child = Child()
    child.hoge()
    # child.fuga() #error
    child.fuga2()

実行結果

nekonisi

26

解説

  • 親クラスParentで,hoge, fugaメソッドを宣言して子クラスChildで使用する。
  • その際に,子クラスのメンバを使用したいが,プライベートメンバだと,親クラスで参照できないためエラーになってしまう。
  • 回避策として,fuga2では子クラスのプライベートメンバを引数として渡してあげて実行している。

問題

  • 複数のプライベートメンバを使用するときに,引数が増えてしまう。
  • 自インスタンスを引数として渡してあげる方法もダメだった。

解決策

  • 会社の先輩に聞いたら,「できるわけねーだろ」とのこと
  • そもそも設計思想がおかしい。
    • 子クラスのメンバを使用したメソッドが親クラスにあること自体がおかしい。
  • 下記のように修正
# coding=utf-8

from abc import ABCMeta, abstractmethod

class Parent(object):

    def __init__(self, name: str, age: int):
        self.__name = name
        self.__age = age
    
    @abstractmethod
    def hoge(self):
        print(self.__name)

    @abstractmethod
    def fuga(self):
        print(self.__age)

class Child(Parent):

    def __init__(self):
        super().__init__('nekonisi', 26)

    def hoge(self):
        super().hoge()

    def fuga(self):
        super().fuga()

if __name__ == '__main__':
    child = Child()
    child.hoge()
    child.fuga()

 

そうすると,コンストラクタのオーバロードとかもしたくなっちゃう。

追記

オーバーロードは下記のように実現する。

# coding=UTF-8

class hoge(object):
    def __init__(self, name=None, age=None):
        if name is None:
            name = 'noname'

        if age is None:
            age = 0

        self.__name=name
        self.__age=age

    def introduce(self):
        print('My name is ' + self.__name)
        print('I\'m ' + str(self.__age) + ' years old.')

if __name__ == '__main__':
    obj1 = hoge()
    obj2 = hoge('nekonisi', 26)
    obj3 = hoge('konisi')

    obj1.introduce()
    obj2.introduce()
    obj3.introduce()

実行結果

My name is noname
I'm 0 years old.
My name is nekonisi
I'm 26 years old.
My name is konisi
I'm 0 years old.

 

以上

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です