안녕하세요.😊
이번 게시글은 제가 python의 class를 공부하며 정리한 글입니다.
class는 객체 지향 프로그래밍의 핵심이며, 초보자들이 python을 공부하다 처음으로 만나는 큰 장벽입니다. class를 잘 다룰 수 있다면 향후 프로그래밍을 할 때 튼튼한 기초가 될 수 있습니다.
Class의 필요성
class를 공부하다보면 쉽게 만나는 예제가 바로 붕어빵입니다. 붕어빵 틀을 만들어 놓으면 붕어빵을 만들 때마다 붕어빵 틀을 만들지 않아도 되고 한 번에 여러 개의 붕어빵을 만들 수 있습니다.
우리는 class를 통해 동일한 구조의 객체를 여러 개 만들 수 있고 손쉽게 관리할 수 있습니다. 또한 코드를 간결하게 작성할 수 있고, 프로그램 유지 보수가 쉬워집니다.
Class와 객체
class는 붕어빵 틀과 비슷합니다. class란 무엇인가를 계속해서 만들어낼 수 있는 틀이고, 객체는 class를 통해 만들어진 것들입니다. class로 만든 객체는 중요한 특징을 가집니다. 바로 객체는 그 자체로 고유하고 동일한 class를 통해 만들어진 다른 객체들과 독립적이라는 것입니다.
class study_programming:
pass
위 코드는 class를 만드는 가장 기본적인 방법입니다. class를 만들기 위해서는 'class'를 선언하고 class 이름을 지정해주면 됩니다. 이후 함수와 동일하게 들여쓰기 후 조건을 작성하면 됩니다. 이런 class로 수 많은 객체를 생성할 수 있습니다.
a = study_programming()
b = study_programming()
a, b라는 객체를 만든 후 함수를 선언하는 것과 동일하게 class 이름과 ()를 붙입니다. 이런 객체는 메모리 용량이 허락하는 한까지 계속해서 만들어낼 수 있습니다.
객체와 instance의 차이
class로 만든 객체를 instance라고도 합니다. 객체와 instance는 지칭하는 대상이 다른데 왜 이름을 다르게 부를까요? 그 이유는 class와의 관계 때문입니다. 위에서 만든 a, b만을 지칭할 때는 '객체'라는 말을 사용하지만 class와 같이 지칭할 때는 'study_programming의 인스턴스'라고 합니다. 즉 인스턴스라는 말은 특정 객체(a)가 어떤 클래스(study_programming)의 객체인지를 관계 위주로 설명할 때 사용합니다.
method(메서드)
메서드란 class에서 실재로 동작하는 함수를 말합니다. class에는 메서드 뿐만 아니라 기본적인 속성도 존재합니다.
class FourCal:
def setdata(self, first, second):
self.first = first
self.second = second
a = FourCal()
a.setdata(3,4)
# a.first = 3, a.second = 4
b = FourCal()
b.setdata(5,8)
# b.first = 5, b.second = 8
다음은 class로 만든 계산기 예제입니다. FourCal class는 계산하기 전 먼저 계산하고 싶은 숫자를 받습니다. setdata는 class 내부에서 def 명령어를 통해 만들어진 method입니다. 먼저 작동하는 구조를 보겠습니다.
- a라는 객체에 class를 선언합니다.
- a.setdata()로 함수를 호출한 후 3, 4를 전달합니다.
- a.first에는 3이 전달되고, a.second에는 4가 전달됩니다.
여기서 self라는 매개변수가 있는데 왜 특정 값을 입력하지 않아도 작동하는지 궁금할 수 있습니다. 여기서 self는 생성된 객체를 의미합니다. 매개변수를 전달하지 않아도 함수를 호출하면 자동으로 객체가 self에 전달됩니다. python의 class에서는 method를 생성할 때 항상 self를 첫 번째 매개변수로 입력해야 합니다.
그리고 여기서 중요하게 짚고 넘어가야 할 것이 있습니다. a 객체를 선언한 후 b 객체를 선언해서 5와 8을 매개변수로 전달하면 a 값이 어떻게 될까요? b의 setdata 매개변수로 5와 8을 전달해도 a.first와 a.second의 값은 변경되지 않습니다.
앞서 말했듯이 객체들은 서로 독립적이라 동일한 class의 인스턴스라 하더라도 객체끼리는 영향을 주지 않습니다.
class FourCal:
def setdata(self, first, second):
self.first = first
self.second = second
def add(self):
result = self.first + self.second
return result
def mul(self):
result = self.first * self.second
return result
def sub(self):
result = self.first - self.second
return result
def div(self):
result = self.first / self.second
return result
a = FourCal()
a.setdata(3,4)
a.add()
# 7
a.mul()
# 12
이렇게 class 기능을 통해 하나의 계산기를 만들어 보았습니다. 계산기의 연산 과정은 다음과 같습니다. 먼저 class FourCal의 인스턴스인 a를 생성합니다. 생성된 a 객체의 method에 3, 4 매개변수를 전달하고 add, mul 등과 같은 메서드를 호출하면 사칙연산 결과를 반환합니다. a.setdata로 전달된 매개변수들이 self.first, self.second의 값으로 사용이 되고 이 값들이 사칙연산 함수들의 연산 과정에 사용이 되는 구조입니다.
상속
class는 '상속'이라는 기능을 적용할 수 있습니다. 상속은 여러 분들이 아시는 것처럼 무언가를 물려받는 것입니다. class는 무엇을 물려받을까요? 상속 받는 class는 이전 class로부터 모든 것을 물려받습니다. 계산기에 기능을 추가하는 예제를 통해 상속에 대해 구체적으로 알아보겠습니다.
class MoreFourCal(FourCal):
pass
상속받는 class는 class 명령어로 생성하고 이전 class를 () 안에 넣어줍니다. 우리가 위에서 FourCal class를 만들 때는 ()를 사용하지 않았습니다. 하지만 상속받는 class에게 어디서 상속받아야 하는지 알려줘야 하므로 ()를 사용해야 합니다. 상속 받지 않을 때도 ()를 사용해도 문제 없지만 원칙적으로는 ()를 사용하지 않아야 합니다.
class MoreFourCal(FourCal):
def pow(self):
result = self.first ** self.second
return result
a = MoreFourCal(4, 2)
a.add()
# 6
a.mul()
# 8
a.sub()
# 2
a.pow()
# 16
상속은 이전 class를 수정한다면 굳이 사용할 필요는 없습니다. 하지만 수정이 허용되지 않는 경우에는 상속의 개념에 대해 알고 있어야 올바른 사용을 할 수 있습니다.
Method overriding
메서드 오버라이딩이란 상속받은 class에서 상속한 class에 있는 매서드를 동일한 이름으로 수정하는 것입니다. 메서드를 오버라이딩 하게 되면 상속한 class의 메서드가 아닌 상속 받은 class의 매서드를 우선적으로 사용합니다.
class SafeFourCal(FourCal):
def div(self):
if self.second == 0:
return 0
else:
return self.first / self.second
위 코드에서 SafeFourCal 안에 div라는 메서드가 생성되었습니다. 상속하는 FourCal과 동일한 메서드가 생성되었지만 SafeFourCal에서는 상속받은 class인 자신의 메서드를 우선적으로 사용합니다.
클래스 변수
class Family:
lastname = '김'
지금까지 사용한 변수는 모두 독립적으로 유지되는 객체 변수입니다. 이번에는 class 내에서 생성되는 class 변수에 대해 알아보겠습니다.
class 변수는 class 내에 자체적으로 생성되는 변수로 객체를 선언하지 않아도 만들 수 있습니다.
class Family:
lastname = '김'
a = Family()
b = Family()
print(a.lastname)
# 김
print(b.lastname)
# 김
Family class에서 선언한 lastname 변수는 인스턴스 a, b에 모두 공유되는 것을 확인할 수 있습니다. 붕어빵 틀을 바꾸면 그 이후 만들어지는 붕어빵들이 모두 변하듯이 인스턴스 변수 모두에 영향을 미칩니다.
만약 Family의 class 변수인 lastname을 변경하게 되면 객체를 새로 선언하지 않아도 a, b의 lastname도 모두 변하게 됩니다.
'Coding Test' 카테고리의 다른 글
| [python] 피자 나눠 먹기(2) (0) | 2023.03.02 |
|---|---|
| [python] 최빈값 구하기 (0) | 2023.02.24 |
| [python] 중앙값 구하기 (0) | 2023.02.24 |
| [python] 분수의 덧셈 (0) | 2023.02.22 |
| [python] 함수 (0) | 2023.01.31 |