관리 메뉴

정리왕

파이썬 클래스 4 (상속과 변수) 본문

6.개발/파이썬 공부하기

파이썬 클래스 4 (상속과 변수)

정리합니다 2020. 11. 29. 16:00
반응형

클래스의 상속

 

상속 (Inheritance)이란 '물려받다'라는 뜻으로, '재산을 상속하다'라고 할 때의 상속과 같은 의미이다. 클래스에도 이 개념을 적용할 수 있다. 어떤 클래스를 만들 때 다른 클래스의 기능을 물려받을 수 있게 만드는 것이다. 이번에는 상속개념을 사용하여 우리가 만든 FourCal 클래스에 a의 b제곱을 구할 수 있는 기능을 추가해보자.

 

앞에서 FoulCal 클래스는 이미 만들어 놓았으므로 FourCal 클래스를 상속하는 MoreFourCal 클래스는 다음과 같이 간단하게 만들 수 있다.

>>> class MoreFourCal(FourCal):
	pass

>>> 

클래스를 상속하기 위해서는 다음처럼 클래스 이름 뒤 괄호 안에 상속할 클래스 이름을 넣어주면 된다.

class 클래스 이름(상속할 클래스 이름)

 

MoreFourCal 클래스는 FourCal 클래스를 상속했으므로 FourCal 클래스의 모든 기능을 사용할 수 있어야 한다.

 

다음과 같이 확인해 보자.

>>> a = MoreFourCal(4, 2)
>>> a.add()
6
>>> a.mul()
8
>>> a.sub()
2
>>> a.div()
2.0

상속받은 FourCal 클래스의 기능을 모두 사용할 수 있음을 확인할 수 있다.

 

 

 

★ 왜 상속을 해야 할까?

보통 상속은 기존 클래스를 변경하기 않고 기능을 추가하거나 기존 기능을 변경하려고 할 때 사용한다.

'클래스에 기능을 추가하고 싶으면 기존 클래스를 수정하면 되는데 왜 굳이 상속을 받아서 처리해야 하지?'라는 의문이 들 수도 있다. 하지만 기존 클래스가 라이브러리 형태로 제공되거나 수정이 허용되지 않는 상황이라면 상속을 사용해야 한다.

 

 

이제 원래 목적인 a의 b제곱을 계산하는 MoreFourCal 클래스를 만들어 보자.

>>> class MoreFourCal(FourCal):
	def pow(self):
		result = self.first ** self.second
		return result

	
>>> 

 

pass 문장은 삭제하고 위와 같이 두 수의 거듭제곱을 구할 수 있는 pow 메서드를 추가해 주었다.

그리고 다음과 같이 pow 메서드를 수행해 보자.

>>> a = MoreFourCal(4,2)		    
>>> a.pow()		    
16

MoreFourCal 클래스로 만든 a 객체에 값 4와 2를 설정한 후 pow메서드를 호출하면 4의2제곱인 16을 돌려주는 것을 확인할 수 있다.

상속은 MoreFourCal 클래스처럼 기존 크래스 FourCal는 그대로 놔둔 채 클래스의 기능을 확장시킬 때 주로 사용한다.

 

 

 

 

메서드 오버라이딩

이번에는 FourCal 클래스를 다음과 같이 실행해 보자.

>>> a = FourCal(4, 0)		    
>>> a.div()		    
Traceback (most recent call last):
  File "<pyshell#110>", line 1, in <module>
    a.div()
  File "<pyshell#84>", line 18, in div
    result = self.first / self.second
ZeroDivisionError: division by zero

FourCal 클래스의 객체 a에 4와 0 값을 설정하고 div메서드를 호출하면 4를 0으로 나누려고 하기 때문에 위와 같은 ZeroDivisionError 오류가 발생한다. 하지만 0으로 나눌 때 오류가 아닌 0을 돌려주도록 만들고 싶다면 어떻게 해야 할까?

 

다음과 같이 FourCal 클래스를 상속하는 SafeFourCal 클래스를 만들어 보자.

>>> class SafeFourCal(FourCal):
	def div(self):
		if self.second == 0:
		    return 0
		else:
		    return self.first / self.second

		    
>>> 

SafeFourCal 클래스는 FourCal 클래스에 있는 div 메서드를 동일한 이름으로 다시 작성하였다. 이렇게 부모 클래스(상속한 클래스)에 있는 메서드를 동일한 이름으로 다시 만드는 것을 메서드 오버라이딩(Overriding, 덮어쓰기)이라고 한다. 이렇게 메서드를 오버라이딩하면 부모클래스의 메서드 대신 오버라이딩한 메서드가 호출된다.

 

SafeFourCal 클래스에 오버라이딩한 div메서드는 나누는 값이 0인 경우에는 0을 돌려주도록 수정했다. 이제 다시 위에서 수행한 예제를 FourCal 클래스 대신 SafeFourCal 클래스를 사용하여 수행해 보자.

>>> a = SafeFourCal(4,0)	    
>>> a.div()
0

FourCal 클래스와는 달리 ZeroDivisionError가 발생하지 않고 의도한 대로 0을 돌려주는 것을 확인할 수 있을 것이다.

 

 

 

 

클래스 변수

객체변수는 다른 객체들에 영향받지 않고 독립적으로 그 값을 유지한다는 점을 이미 알아보았다. 이번에는 객체변수와는 성격이 다른 클래스 변수에 대해 알아보자.

다음 클래스를 작성해 보자.

>>> class Family:
	lastname = "kim"

		    
>>> 

Family 클래스에 선언한 lastname이 바로 클래스 변수이다. 클래스 변수는 클래스 안에 함수를 선언하는 것과 마찬가지로 클래스 안에 변수를 선언하여 생성한다.

이제 Family 클래스를 다음과 같이 사용해 보자.

>>> print(Family.lastname)    
kim

클래스 변수는 위 예와 같이 클래스 이름.클래스 변수로 사용할 수 있다.

 

 

 

또는 다음과 같이 Family 클래스로 만든 객체를 통해서도 클래스 변수를 사용할 수 있다.

>>> a = Family()	    
>>> b = Family()	    
>>> print(a.lastname)	    
kim
>>> print(b.lastname)	    
kim

만약 Family 클래스의 lastname을 다음과 같이 'park'이라는 문자열로 바꾸면 어떻게 될까?

>>> Family.lastname = "park"

다음과 같이 확인 해 보자.

>>> print(a.lastname)	    
park
>>> print(b.lastname)    
park

클래스 변수 값을 변경했더니 클래스로 만든 객체의 lastname 값도 모두 변경된다는 것을 확인할 수 있다. 즉 클래스 변수는 클래스로 만든 모든 객체에 공유된다는 특징이 있다.

 

 

 

id함수를 사용하면 클래스 변수가 공유된다는 사실을 증명할 수 있다.

>>> id(Family.lastname)		    
4360692936
>>> id(a.lastname)	    
4360692936
>>> id(b.lastname)	    
4360692936

id값이 모두 같으므로 Family.lastname, a.lastname, b.lastname은 모두 같은 메모리를 가리키고 있다.

 

클래스 변수를 가장 늦게 설명하는 이유는 클래스에서 클래스 변수보다 객체변수가 훨씬 중요하기 때문이다. 실무 프로그래밍을 할 때도 클래스 변수보다는 객체변수를 사용하는 비율이 훨씬 높다.

 

 

 

반응형
Comments