初めてのPython(25章前編)

IS-A関係, HAS-A関係

A is a Bから来ているのがIS-A関係。
「AはBの一種」なので、Aの中でさらに何かに特化したのがB。

A has a Bから来ているのがHAS-A関係。
「AはBを含んでいる」なので、AはBの構成要素。

参考:オブジェクト思考 is-a関係とhas-a関係:継承と包含

会社で考える*1と、

  • 会社は従業員からできている(has-a:会社を分割して特徴を見いだしている)
  • 従業員の中には以下のような部門の人がいる(is-a:従業員を分類して特徴を見いだしている)
    • 管理部門
    • 営業部門
    • 開発部門
      • ソフトウェア開発部門
      • ハードウェア開発部門
[kobakoba0723@fedora13-intel64 ~]$ cat is_a.py
#!/usr/bin/env python

class Employee(object):
  def __init__(self, name, job=None):
    self.name = name
    self.job = job
  def dothejob(self):
    print 'do the job'
  def __repr__(self):
    return '<Employee: name=%s, job=%s>' % (self.name, self.job)

class Management(Employee):
  def __init__(self, name):
    Employee.__init__(self, name, 'management')
  def dothejob(self):
    print '%s run the company' % (self.name, )

class Sales(Employee):
  def __init__(self, name):
    Employee.__init__(self, name, 'sales')
  def dothejob(self):
    print '%s sell a product' % (self.name, )

class Engineer(Employee):
  def __init__(self, name):
    Employee.__init__(self, name, 'engineer')
  def dothejob(self):
    print '%s create a product' % (self.name, )

class HardwareEngineer(Engineer):
  def __init__(self, name):
    Employee.__init__(self, name, 'hardware-engineer')
  def dothejob(self):
    print '%s create a hardware' % (self.name, )

class SoftwareEngineer(Engineer):
  def __init__(self, name):
    Employee.__init__(self, name, 'software-engineer')
  def dothejob(self):
    print '%s create a software' % (self.name, )


if __name__ == '__main__':
  employee_type_list = [Employee, Management, Sales, Engineer, HardwareEngineer, SoftwareEngineer]
  
  for employee_type in employee_type_list:
    person = employee_type(employee_type.__name__)
    print '%s: ' % (person, ),
    person.dothejob()
[kobakoba0723@fedora13-intel64 ~]$ cat has_a.py 
from is_a import Management, Sales, HardwareEngineer, SoftwareEngineer

class Customer(object):
  def __init__(self, name):
    self.name = name
  def order_product(self, sales_person):
    print '%s order product-A to %s' % (self.name, sales_person)
  def pay_product(self, mng_person):
    print '%s pay to %s' % (self.name, mng_person)
  def get_product(self, sales_person):
    print '%s get product-A from %s' % (self.name, sales_person)

class Factory(object):
  def produce(self):
    print 'product a product-A with hardware and software'

class Company(object):
  def __init__(self):
    self.mng = Management('taro')
    self.sales = Sales('jiro')
    self.hard_eng = HardwareEngineer('saburo')
    self.soft_eng = SoftwareEngineer('shiro')
    self.factory = Factory()
  
  def order(self, name):
    customer = Customer(name)
    customer.order_product(self.sales.name)
    self.hard_eng.dothejob()
    self.soft_eng.dothejob()
    self.factory.produce()
    self.sales.dothejob()
    customer.pay_product(self.mng.name)
    customer.get_product(self.sales.name)
    self.mng.dothejob()

if __name__ == '__main__':
  business = Company()
  business.order('John')
[kobakoba0723@fedora13-intel64 ~]$ python has_a.py 
John order product-A to jiro
saburo create a hardware
shiro create a software
product a product-A with hardware and software
jiro sell a product
John pay to taro
John get product-A from jiro
taro run the company
[kobakoba0723@fedora13-intel64 ~]$ 

is_a.pyでやってるemployee_type_listの代入処理を、
"Employee"とか使って、しかも先頭でやってたもんだから、いっぱい怒られた。

  • "Employee"ってやると文字列だから、文字列に__name__なんて属性はない!
  • Employeeって直したら、classステートメントよりも前だから、Employeeなんて属性未定義だ!

*1:他にも色々とあるんだろうけど、ここでは簡素化のために色々と無視