클래스와 객체
클래스(Class)
클래스와 객체는 길가에서 파는 붕어빵으로 간단히 비유하여 이해할 수 있습니다.
프로그래머 관점에서는 붕어빵을 찍어낼 수 있는 틀을 클래스(class)라고 이해할 수 있으며, 붕어빵 틀에서 찍혀 나온 붕어빵 하나하나를 객체(object)라고 이해할 수 있습니다.
이처럼 클래스(class)란 무언가를 계속 똑같이 찍어낼 수 있는 설계도와도 같은 것을 의미합니다.
또한 객체(object)란 설계도, 즉 클래스를 바탕으로 찍어낸 제품과도 같은 것을 의미합니다.
다음의 예제에서 클래스와 객체를 구분해봅시다.
예제
1. 영희 / 사람
2. 영철 / 학생
3. 파이썬 / 프로그래밍 언어
4. 코*콜라 1.5L 페트병 / 음료
5. 1997년에 생산된 500원 / 동전
6. 베이지 천 소파 / 소파
7. 검은 가죽 소파 / 소파
위의 예제에서 왼쪽은 객체로 볼 수 있고 오른쪽은 클래스로 볼 수 있습니다.
오른쪽을 기준으로 서로 다른 객체들이 존재하는 것을 확인할 수 있습니다.
소파라는 틀 안에서 베이지색 천으로 만들어진 소파와 검은색 가죽으로 만들어진 소파가 나올 수 있습니다. 하지만 그들은 여전히 소파라는 틀을 공유합니다.
여러분은 이제 ‘절차지향’ 프로그래밍을 벗어나 ‘객체지향’ 프로그래밍의 세계에 들어왔습니다.
클래스 구성
클래스는 크게 두 가지로 구성됩니다.
1. 속성
2. 동작
속성은 클래스가 가지는 변수들을 의미합니다.
예를 들어 은행 계좌에는 잔액, 계좌의 주인, 이자율 등이 있을 수 있습니다.
동작은 클래스가 할 수 있는 동작들을 의미합니다.
은행 계좌에서 우리는 출금, 입금, 계좌 폐쇄 등을 할 수 있습니다.
사람으로 예를 들자면 속성에는 이름, 나이, 성별, 주소지 등이 들어갈 수 있고, 동작에는 앉기, 일어서기, 걷기, 운동하기 등이 들어갈 수 있는 것입니다.
이처럼 세상에 이미 존재하거나 우리가 만들 무언가에 대해 속성과 동작을 분리해서 분석해보는 습관을 들이면 이후에 클래스를 디자인하는데 훨씬 쉽게 접근할 수 있습니다.
그리고 이런 사고방식으로 프로그래밍을 설계하는 것을 객체 지향 프로그래밍(Object Oriented Programming)이라고 합니다.
객체(Object)
하나의 클래스로부터 여러 개의 객체(object)가 생성될 수는 있지만 각각은 서로 유일(unique)합니다.
서로 다른 객체는 특별히 선언한 문장이 없으면 서로 완전히 독립적입니다.
즉, 내가 한 객체의 A라는 속성값을 변경하여도 다른 객체의 A 속성값은 변하지 않습니다.
객체 지향의 개념
1. Abstraction(추상화) - 만들고자 하는 것들의 공통적인 것을 바탕으로 하나로 묶는 것
2. Encapsulation(캡슐화) - 맡은 역할의 수행을 위해 최소한의 외부 접근만을 허용하는 것
3. Polymorphism(다형성) - 자료형에 구애 받지 않고 프로그래밍 하는 것
4. Inheritance(상속) - 하위 개념이 상위 개념의 속성 및 동작 등을 물려받는 것
더 자세한 내용은 약간 어려운 내용이므로 구글 등에서 객체지향 프로그래밍이나 OOP로 검색하여 알아보길 바랍니다.
클래스 선언
파이썬에서 클래스를 선언하는 방법은 다음과 같습니다.
클래스 선언
class Horse:
클래스는 class 키워드와 함께 만들고자 하는 클래스의 이름을 나열하여 선언합니다.
파이썬에서 클래스의 이름은 일반적으로 대문자로 시작합니다.
생성자(Constructor) 선언
생성자 선언
class Horse:
def __init__(self, age, height, color, xpos, ypos):
self.age = age
self.height = height
self.color = color
self.xposition = xpos
self.yposition = ypos
self.velocity = 0
우리가 horse 클래스라는 설계도를 얻었다고 가정합시다.
이 설계도를 바탕으로 세상에 실제 Horse가 태어나게 해주는 것이 바로 생성자(constructor)입니다.
파이썬에서 생성자의 이름은 항상 __init__으로 고정되며, 다른 이름으로 변경할 수 없습니다.
또한, 생성자의 첫번째 매개변수는 반드시 self로 선언해야 합니다.
self 키워드
클래스 외부에서 해당 함수를 호출한 객체를 찾는 일은 객체의 이름만 알면 쉽게 찾을 수 있습니다.
하지만 클래스 내부에서 호출한 객체를 찾으려면 마땅한 방법이 없습니다.
그래서 도입된 것이 바로 self 키워드입니다.
파이썬에서 self 키워드는 해당 함수를 호출한 객체를 가리킵니다.
C++과는 다르게 파이썬은 클래스 내부 변수를 미리 선언하지 않고 사용합니다.
아래의 두 코드는 정확히 같은 동작을 하는 코드입니다.
C++ | Python |
---|---|
class Person{ int age; public : Person(){ this->age = 17; } } |
class Person: def __init__(self): self.__age = 17 |
private 키워드
private 키워드는 클래스 외부에서 클래스 내부의 멤버에 접근하지 못하도록 하는 키워드로 JAVA나 C++에서 사용합니다.
하지만 파이썬에서는 private 키워드를 사용하지 않고, 변수 앞에 언더스코어(_) 두 개를 붙여서 표현합니다.
private 키워드로 설정된 내부 멤버에는 해당 객체 내에서만 접근할 수 있습니다.
같은 클래스에서 생성된 객체라더라도 서로 다른 객체의 private 멤버에는 접근할 수 없습니다.
public 키워드
public 키워드는 private 키워드와는 반대되는 개념으로 클래스 내부나 외부든 어디에서나 접근할 수 있는 멤버들을 의미합니다.
파이썬에서는 private 키워드와 마찬가지로 public 키워드를 사용하지 않고, 변수의 앞과 뒤에 언더스코어(_) 두 개를 붙여서 표현합니다.
대표적인 예가 앞서 살펴본 생성자입니다. (__init__)
인스턴스화
클래스에 생성자를 만들었다면 이제 실제로 사용해봅시다.
예제
if __name__ == '__main__':
danbi = Horse(5, 160, 'brown', 0, 0)
클래스에서는 생성자를 호출하여 객체를 만드는데 이러한 과정을 인스턴스화라고 합니다.
이때 생성자 이름인 __init__을 호출하는 것이 아닌 클래스 이름을 호출하여 객체를 생성하게 됩니다.
그리고 생성자의 매개변수 목록과 실제 전달 인수를 순서까지 잘 맞춰 전달해 주어야 합니다.
클래스 변수
앞서 같은 클래스에서 생성된 객체라도 서로 완전히 독립적이라고 했습니다.
하지만 이러한 객체끼리 정보를 공유하는 방법이 완전히 없는 것은 아닙니다.
바로 클래스 변수라는 것을 사용하면 같은 클래스에서 생성된 객체들끼리 정보를 공유할 수 있습니다.
다음 예제는 Alphabets라는 클래스에서 6개의 객체를 생성하여 python이라는 문자열을 출력하는 예제입니다.
예제
class Alphabets:
__str = ""
def __init__(self, text):
self.text = text
Alphabets.__str += text
def print_class_variable(self):
print (Alphabets.__str)
if __name__ == '__main__':
o1 = Alphabets('p')
o2 = Alphabets('y')
o3 = Alphabets('t')
o4 = Alphabets('h')
o5 = Alphabets('o')
o6 = Alphabets('n')
o1.print_class_variable()
o5.print_class_variable()
실행 결과
python
python
위의 예제에서 객체 o1과 o5가 같은 메소드인 print_class_variable() 함수를 호출하고 있으나 그 실행 결과가 같은 것을 확인할 수 있습니다.
이것은 6개의 객체가 생성되는 과정에서 Alphabets 클래스의 클래스 변수인 str이 서로 공유되기 때문입니다.
따라서 실행된 결과가 순서대로 문자 'p', 'y', 't', 'h', 'o', 'n'이 연결되어 ‘python’이라는 문자열을 출력하게 됩니다.