-
클래스 - 클래스 관계python 2021. 3. 11. 23:30
1.클래스 관계
IS-A
IS-A는 '~은 ~의 한 종류다'라는 의미다. 예를 들어 '노트북은 컴퓨터의 한 종류다'라는 문장은 관계가 성립하므로 Computer 클래스와 Laptop 클래스는 IS-A 관계다. 영어로는 'A laptop IS-A computer'인데 '한 종류다'라는 의미가 IS-A이므로 IS-A 관계라고 부른다.
IS-A 관계를 프로그램에서 표현할 때는 상속(inheritance)을 사용한다. 상속은 객체 지향의 근간이라고 불릴 만큼 중요하며 유용하다. 하지만 IS-A 관계가 아닐 때 상속을 하면 클래스를 설계하는 데 어려움이 따른다.
상속 관계에서 상속을 하는 클래스를 기본(base)클래스, 부모(parent)클래스, 슈퍼(super)클래스라고 하며 상속을 받는 클래스를 파생(derived)클래스, 자식(child)클래스, 서브(sub)클래스라고 한다.
노트북(laptop class)과 컴퓨터(computer class)를 상속을 이용해 설계해보자.
#code 1-1 class Computer: def __init__(self, cpu, ram): self.CPU = cpu self.RAM = ram def browse(self): print("browse") def work(self): print("work")
code 1-1은 기본 클래스인 Computer 클래스를 보여준다. 인스턴스 멤버는 CPU와 RAM이고, 인스턴스 메서드는 browse()와 work()다. 노트북은 컴퓨터의 모든 멤버와 메서드를 가진다.(노트북도 CPU와 RAM이 있으며 웹 서핑을 할 수 있으며 일을 수행할 수 있다.) 이렇게 어떤 객체가 다른 객체의 모든 특성(멤버)과 기능(메서드)을 가진 상태에서 그 외에 다른 특성이나 기능을 가지고 있다면 상속이 가장 어울린다.
#code 1-2 class Laptop(Computer): #멤버 추가 def __init__(self, cpu, ram, battery): super().__init__(cpu, ram) self.battery = battery #메서드 추가 def move(self, to): print("move to {0}".format(to))
슈퍼 클래스(Computer)에 Laptop의 특징을 반영하여 클래스를 설계했다.
super().__init__(cpu, ram) 문장을 보면 Computer 클래스의 생성자를 호출하면서 두개의 인자를 전달한다. super는 현재 클래스의 슈퍼 클래스를 의미한다. CPU와 RAM은 슈퍼 클래스의 생성자를 이용해 초기화 했으므로 나머지 한 멤버인 battery만 할당해 주면 된다.
HAS-A : 합성 또는 통합
HAS-A 관계는 '~이 ~을 가진다 혹은 포함한다'는 의미다. 컴퓨터는 CPU와 RAM을 가진다. 'A Computer HAS-A CPU'에서 '가지고 있다'는 의미가 HAS-A이므로 HAS-A 관계라고 부른다.
프로그램에서 HAS-A 관계는 합성(composition) 혹은 통합(aggregation)을 이용해 표현한다. 합성과 통합은 모두 HAS-A 관계를 나타내는 방법이지만, 둘 사이에는 차이점이 있다. 컴퓨터와 CPU의 관계를 합성으로 표현하고 경찰과 총의 관계를 통합으로 나타내 둘의 차이를 비교해보자.
#code 2-1 class CPU: pass class RAM: pass class Computer: def __init__(self): self.cpu = CPU() self.ram = RAM()
Computer 클래스는 인스턴스 멤버 cpu를 가진다. 생성자에서 CPU 객체를 생성하여 멤버 cpu에 할당한다. 즉, Computer 객체가 생성될 때 CPU 객체도 같이 만들어졌다가 사라질 때 함께 사라진다. Computer 객체와 CPU 객체는 객체의 생명주기가 같고 컴퓨터가 CPU를 소유하고 있는 모양새다. 굉장히 강한 관계를 맺고 있는데, 이러한 관계를 합성이라고 한다.
#code 2-2 class Gun: def __init__(self, kind): self.kind = kind def bang(self): print('bang bang') class Police: def __init__(self): self.gun = None def acquire_gun(self, gun): self.gun = gun def release_gun(self): gun = self.gun self.gun = None return gun def shoot(self): if self.gun: self.gun.bang() else: print("Unable to shoot")
Police 객체가 만들어질 때 아직 Gun 객체를 가지고 있지 않다. 이후 acquire_gut() 메서드를 통해 Gun 객체를 멤버로 가지게 된다. 또한 release_gun() 메서드를 통해 갖고 있던 총을 반납할 수 있다. 이 두 메서드를 이용하면 총을 가진 경찰과 총을 가지고 있지 않은 경찰을 모두 표현할 수 있다.
경찰과 총의 관계는 분명 컴퓨터와 CPU의 관계와는 다르다. Police 객체가 생성될 때 Gun 객체는 생성되지 않고, Police 객체는 Gun 객체를 언제든지 반납할 수 있다. 즉, Police 객체와 Gun 객체는 생명주기를 함께 하지 않는 상대적으로 약한 관계다. 이러한 관계를 통합이라고 한다.
'python' 카테고리의 다른 글
파이썬 - 인수(argument) (0) 2021.03.16 클래스 - 메서드 오버라이딩과 다형성 (0) 2021.03.11 객체 지향 프로그래밍 (0) 2021.03.05 파이썬 - 절차지향 프로그래밍 (0) 2021.03.04 함수 (0) 2021.03.03