is-a는 말 그대로 ㅇㅇ는 ㅇㅇ이다 라는 의미이다. 상속이라고도 한다. 어떠한 클래스가 다른 클래스의 메소드, 속성을 물려받는 것을 상속이라고 말한다. 우리가 알고 있는 상속이라는 단어처럼 부모, 자식간의 관계라고 생각하면 된다. 물려주는 클래스는 부모클래스, 물려받는 클래스는 자식클래스라고 한다. 예를 들어 '트럭은 자동차이다.' 라고 한다면 트럭은 자동차의 속성과 기능을 받게 되고 자동차는 부모클래스, 트럭은 자식클래스가 된다.
옷 클래스를 예로 들어 보자. 옷은 어떤 타입인지, 어떤 종류인지, 무슨 사이즈 인지 등 속성을 가지고 있다. 옷 중에서 치마는 옷 클래스를 상속받는 또 다른 클래스로 정의될 수 있다.
# 옷 클래스
class Clothes:
def __init__(self, type, name, size):
self.type = type
self.name = name
self.size = size
def about_clothes(self):
print('어떤 타입인지? : ', self.type, ', 어떤 옷인지? : ', self.name, ', 사이즈는 어떻게 되는지? : ', self.size)
# 옷 클래스 상속
class Skirt(Clothes):
pass
# 치마 클래스 객체 선언
mini_skirt = Skirt('하의', '치마', '55')
# 부모 클래스인 옷 클래스의 메소드 호출
mini_skirt.about_clothes()
# 결과
어떤 타입인지? : 하의 , 어떤 옷인지? : 치마 , 사이즈는 어떻게 되는지? : 55
위의 코드처럼 skirt 클래스는 clothes 클래스를 상속받아 속성과 메소드를 그대로 호출하여 사용할 수 있다. 이게 is-a, 상속이다.
has-a 도 말 그대로 ㅇㅇ는 ㅇㅇ를 가지고 있다라는 의미이다. 어떠한 객체가 다른 객체를 포함하고 있다는 말이다.
위의 예시처럼 옷으로 설명하자면 옷을 보관하는 옷장 클래스와 옷 클래스로 설명할 수 있다. 옷장은 옷을 넣을 수 있는 최대 개수와, 공간 등이 있다.
# 옷장 클래스
class Closet:
def __init__(self):
self.opened = False
self.remaining_space = 10
self.item_space = []
def open(self):
self.opened = True
print('옷장을 열었습니다.')
def close(self):
self.opened = False
print('옷장을 닫았습니다.')
# 옷장에 옷을 넣는 메소드
def put(self, some):
if self.opened:
self.item_space.append(some)
self.remaining_space -= 1
else:
print('옷장을 여세요.')
class Clothes:
pass
mini_skirt = Clothes()
closet = Closet()
closet.put(mini_skirt)
closet.open()
closet.put(mini_skirt)
print('옷장 보관 공간 : ', closet.item_space)
# 결과
옷장을 여세요.
옷장을 열었습니다.
옷장 보관 공간 : [<__main__.Clothes object at 0x10b744070>]
결과를 보면 Clothes 객체가 옷장 클래스의 객체로 들어간 것을 확인 할 수 있다. 이런식으로 어떤 객체가 다른 객체를 인스턴스로 가지고 있는 것을 has-a 상속이라고 한다.