티스토리 뷰

반응형

객체지향 개념이 나타나기 이전의  프로그래밍 방법에서는 프로그램이 어떤 일을 하고 나서, 그다음엔 어떤 일을 하고, 또 그다음엔 뭘 하라는 식으로 컴퓨터가 해야 할 일을 알려주기에 바빴습니다.

그런데 객체지향 프로그래밍(Object-Oriented Programming)에서는 프로그램을 작성할 대상이 되는 실제 세계의 사물(객체)을 그대로 표현하고, 그것들이 어떻게 움직이는지 정해주고 나서야 비로소 그 객체들에게 일을 시킵니다. 객체지향 프로그래밍을 잘 사용하면 보다 좋은 프로그램을 빨리 만들 수 있고, 나중에 수정하기도 편해진다고 합니다. 프로그래밍 언어들이 모두 객체지향적인 것은 아니지만, 요즘에 널리 사용되는 언어 중에는 객체지향을 지원하는 것이 많습니다.

파이썬은 꼭 객체지향적으로 작성하지 않아도 됩니다. 다시 말씀드려서, 앞으로의 강좌를 보지 않으셔도 간단한 프로그램을 작성하는 데 문제가 없다는 것이죠.

하지만 객체지향에 대해 이해하시고 나면 파이썬으로 윈도우 프로그래밍을 하거나, 복잡한 프로그램을 작성하는 데 많은 도움이 됩니다. 또, 다른 프로그래밍 언어를 이해하기도 수월해지지요.

클래스? 인스턴스?

‘김연아’는 실제로 존재하죠? 네, 여러분이 생각하시는 그 김연아 맞아요. ㅎㅎ ‘김동성’도 실제로 존재하죠? 두 사람 다 실제로 존재하는 사람입니다.

두 사람의 공통점은 무엇일까요? 여러 가지를 들 수 있겠지만 둘 다 ‘스케이터’라는 공통점을 갖고 있지요.

‘스케이터’라는 단 하나의 사람이나 물건이 실제로 존재할까요? 그렇지는 않습니다. 하지만 우리는 ‘스케이트 타는 사람’을 ‘스케이터’라고 부릅니다. 이런 것을 일컫는 말이 클래스(class)입니다. 우리말로 옮기기는 쉽지 않지만 ‘부류’라는 의미로 생각하시면 좋을 것 같아요.

다른 예를 들어볼까요?

‘사과’는 클래스이구요, ‘내가 엊저녁에 먹은 사과 다섯 개 중에 두 번째 것’이라고 콕 찍어서 말해주면 실체(instance)로 봐줄만합니다.

‘좋은 집’은 실체일까요? 어느 한 집만을 콕 찍어서 ‘좋은 집’이라고 하기는 힘들 것 같군요. 그럼 ‘우리 집’은 실체일까요? 그건 실체라고 해도 될 것 같네요. 단, 집을 여러 채 가진 사람이 ‘우리 집’이라고 말할 때는 정확히 어느 집을 가리키는 것인지 알 수 없겠죠. 프로그램 작성을 위해 클래스를 설계하다보면 이런 애매한 문제를 만날 때도 있지요.

 

파이썬의 클래스

이제 파이썬으로 부류와 실체를 표현해 보겠습니다.

>>> class Singer:                      # 가수를 정의하겠느니라…
...     def sing(self):                # 노래하기 메서드
...            return "Lalala~"
...    
>>> taeji = Singer()                   # 태지를 만들어랏!
>>> taeji.sing()                       # 노래 한 곡 부탁해요~
'Lalala~'

클래스를 만들 때는 위와 같이 class 클래스이름: 형식으로 시작해서 그 다음부터 그 클래스의 성질이나 행동을 정의해주면 됩니다. 둘째 줄에는 함수가 정의되어 있죠? 이와 같이 클래스 내부에 정의된 함수를 메서드(method)라고 부릅니다.

여기서 sing 메서드는 Singer라는 클래스가 하는 행동을 정의하고 있죠. Singer 클래스를 만든 다음에는 taeji라는 객체를 만들었습니다. 인스턴스명 = 클래스()와 같이 만들면 되죠.

그 다음엔 그렇게 만들어진 taeji에게 노래를 시켜봤습니다. Singer 클래스에 sing 메서드를 정의해줬기 때문에 Singer 클래스에 속한 taeji 객체도 sing 메서드를 사용할 수 있지요. 다시 말해서 가수는 노래할 수 있으니까 태지라는 가수도 역시 노래를 할 수 있는 것입니다. 이와 같이 어떤 객체의 메서드를 사용할 때는 객체.메서드 형식으로 해주시면 됩니다.

 

이번엔 같은 방법으로 리키 마틴 객체를 만들어서 노래를 청해보세요.

>>> ricky = Singer()
>>> ricky.sing()
'Lalala~'

 

 

이렇듯 실제 세계에 존재하는 실체(instance)를 객체(object)라고 하고, 객체들의 공통점을 간추려서 개념적으로 나타낸 것이 클래스(class)라고 합니다.

 

변수와 메서드

어떤 클래스를 만들려면 그 객체가 갖는 성질과 그 객체가 하는 행동을 정의해주면 된다고도 했고요. 디아블로2 게임의 아마존이라는 캐릭터를 클래스로 표현해 볼까요?

class Amazon:
    strength = 20
    dexterity = 25
    vitality = 20
    energy = 15

    def attack(self):
        return 'Jab!!!'

아마존 클래스가 갖고 있는 힘, 기술, 체력, 에너지라는 네 가지 성질은 변수로 나타내었구요, '공격'하는 행동은 메서드로 나타내었습니다.

>>> jane = diablo2.Amazon()
>>> mary = diablo2.Amazon()

두 명의 여전사가 탄생했습니다. 짜잔~

 

jane과 mary는 둘 다 Amazon으로서 필요한 자질을 모두 갖추고 있겠죠? 그렇다면 jane의 힘도, 공격하는 행동도 Amazon 클래스에서 정의한 그대로이겠구요.

>>> jane.strength
20
>>> jane.attack()
'Jab!!!'

이렇게 객체는 클래스에서 정의해준 변수와 메서드를 그대로 갖게 됩니다. 별로 어렵지 않죠? 여기서 주의해서 보실 것은 메서드를 정의할 때와 사용할 때는 차이가 있다는 점입니다. Amazon 클래스에서 메서드를 정의할 때는 def attack(self):와 같이 self라는 인자를 받았는데, jane 객체의 메서드를 호출할 때는 그냥 attack()이라고 했지요?

self

self라는 것은 바로 그 클래스의 객체를 가리키는데, jane과 mary가 똑 같은 attack 메서드를 가지기 때문에 서로 구별하기 위해서 사용한 것입니다. 한마디로, 메서드를 정의할 때는 항상 self라는 인자를 써준다고 생각하시면 되겠네요. self를 어떻게 사용하는지 좀 더 살펴보기 위해 Amazon 클래스에 메서드를 추가해 봅시다.

    def exercise(self):
        self.strength += 2
        self.dexterity += 3
        self.vitality += 1

이 메서드는 훈련을 하면 힘, 기술, 체력이 올라가는 것을 표현했지요. diablo2.py 파일의 Amazon 클래스에 이 메서드를 추가하고 저장해주시기 바랍니다. 저장하셨으면 F5 키를 다시 한번 눌러서 diablo2 모듈을 다시 실행하고, 임포트도 해준 다음에, 새로운 객체를 만들어서 훈련을 시켜보세요.

>>> eve = diablo2.Amazon()
>>> eve.exercise()
>>> eve.strength
22

힘(strength)이 세졌네요. 훈련한 보람이 있지요?

 

 

상속

다음으로 알아볼 내용은 객체지향 프로그래밍의 핵심적인 개념 가운데 하나인 상속(inheritance)입니다. 상속이란 어떤 클래스가 다른 클래스의 성질을 물려받는 것을 말하지요.

어떤 클래스를 만들 때 처음부터 모든 것을 새로 만들 필요 없이, 핵심적인 성질을 갖고 있는 다른 클래스로부터 상속을 받아서 조금만 손을 보면 쓸만한 클래스를 만들 수 있답니다.

예제를 보실까요?

class Person:
    # 눈 두 개, 코 하나, 입 하나...
    eyes = 2
    nose = 1
    mouth = 1
    ears = 2
    arms = 2
    legs = 2

    # 먹고 자고 이야기하고...
    def eat(self):
        print('얌냠...')

    def sleep(self):
        print('쿨쿨...')

    def talk(self):
        print('주절주절...')

위의 Person이라는 클래스는 보통 사람을 나타낸 클래스입니다. 눈, 코, 입, 팔다리가 다 있고, 먹고, 자고 이야기도 하지요.

이번에는 학생이라는 클래스를 만들어 봅시다. 학생도 사람이니까 사람이 갖는 여러 성질이나 행동은 모두 갖고 있을 것이고, 거기에 학생만의 특징을 좀 더 갖도록 하면 되겠지요? 하지만, 사람 클래스도 한참 걸려서 입력했는데, 또다시 학생클래스의 눈, 코, 입부터 시작해서 모든 것을 새로 만들어주려면 너무 귀찮겠네요.

바로 이럴 때 다음과 같이 상속을 이용하면 손쉽게 학생 클래스를 만들 수 있답니다.

class Student(Person):     # Person 클래스를 상속받음
    def study(self):
        print('열공열공...')

위의 Student 클래스는 Person 클래스를 상속받았습니다. 우리가 Student 클래스를 눈, 코, 입부터 하나하나 다시 만들어 주지 않더라도 Person의 성질들을 모두 물려받아서 갖게 된 것이죠. 우리는 여기에 study라는 메서드만 하나 더 써주어서 우아하게 마무리를 했습니다.

굳이 상속을 받지말고 스크립트를 복사해서 붙이면 되지않느냐고요? 물론 그렇게 해도 가능합니다.

 

하지만 나중에 사람과 학생 클래스에 '옷 색깔'이라든지, '싸우다' 같은 것들을 추가하고 싶어진다면, 그때마다 사람 클래스와 학생 클래스를 각각 수정해야 되겠지요.

사람과 학생의 관계를 위와 같이 그림으로 표현할 수도 있습니다. 사각형은 각각의 클래스를 나타내고, 그 안에 클래스의 이름과 변수, 메서드를 적어주었습니다. 화살표는 '상속 관계'를 나타내고, 그 방향은 하위 클래스로부터 상위 클래스를 향합니다.

이 화살표를 따라가면서 'is a'라고 읽으면 두 클래스의 관계를 쉽게 파악할 수 있지요.

"A Student is a Person.(학생은 사람이다)"이 되는군요.

클래스들의 관계를 이렇게 그림으로 그리면 클래스를 설계하거나 분석할 때 이해하기 쉽답니다.

그럼, 과연 Student 클래스가 Person 클래스의 모든 성질을 똑같이 갖고 있는 것인지도 확인해 보도록 하죠. 먼저 위의 예제들을 파일로 저장해서 import하시거나, 그냥 인터프리터에서 입력하신 다음에 아래와 같이 테스트를 해보세요.

>>> lee = Person()
>>> lee.mouth
1
>>> lee.talk()
주절주절...
>>> kim = Student()
>>> kim.mouth
1
>>> kim.talk()
주절주절...

Person 클래스의 객체인 lee와 Student 클래스의 객체 kim이 하는 짓들이 똑같지요? Person 클래스로부터 상속받았기 때문에 그렇다는 것을 아실 수 있겠죠? 그러나, 상속 받은 것으로 끝이 아니지요. Student는 공부라는 새로운 메소드도 가지고 있습니다.

>>> kim.study()
열공열공...

역시 kim은 학생답게 공부도 열심히 하는군요^^

 

 

 

초기화

이번엔 클래스를 생성과 함께 초기화하는 법에 대해 알아보겠습니다.

__init__ 메서드 (초기화)

# bookstore.py

class Book:

    def setData(self, title, price, author):
        self.title = title
        self.price = price
        self.author = author

    def printData(self):
        print('제목 : ', self.title)
        print('가격 : ', self.price)
        print('저자 : ', self.author)

    def __init__(self):
        print('책 객체를 새로 만들었어요~')

예제로 Book(책) 클래스를 갖는 bookstore(책방) 모듈을 만들어 보았습니다.

책 클래스의 메서드로는 책 제목, 가격, 저자와 같은 자료들을 입력할 때 사용할 setData()와 이런 자료들을 출력해주는 printData()를 만들어 주었지요.

그리고 __init__이라는 메서드도 있지요? 이것이 바로 파이썬에서 특별하게 약속된 메서드 가운데 하나로, 초기화(initialize) 메서드라고도 합니다.

어떤 클래스의 객체가 만들어질 때 자동으로 호출되어서 그 객체가 갖게 될 여러 가지 성질을 정해주는 일을 하지요. 그럼 책 클래스의 객체를 하나 만들어볼까요?

>>> import bookstore
>>> b = bookstore.Book()  
책 객체를 새로 만들었어요~

Book()해서 Book 객체를 만들자마자 초기화 메서드가 실행되었군요. 나머지 setData와 printData 메서드들은 다음과 같이 사용하시면 됩니다.

>>> b.setData('누가 내 치즈를 먹었을까', '300원', '미키')
>>> b.printData()
제목 :  누가 내 치즈를 먹었을까
가격 :  300원
저자 :  미키

이제 초기화 메서드가 뭔지 대충 감을 잡으셨으면 __init__ 메서드를 사용해서 실제로 객체를 초기화시켜보겠습니다. __init__ 메서드를 아래와 같이 수정해 보세요.

    def __init__(self, title, price, author):
        self.setData(title, price, author)
        print('책 객체를 새로 만들었어요~')

객체를 생성시킬 때 제목, 가격, 저자를 인자로 받아서, setData 메서드에게 넘겨주도록 했죠? 물론 초기화 메서드에서 직접 변수를 다뤄도 상관없지만 setData 메서드를 미리 만들어뒀으니까 이용을 한 것입니다. 이제부터 책 객체를 만들 때는 다음과 같이 세 개의 인자를 넘겨줘야 합니다.

>>> from importlib import reload
>>> reload(bookstore)
>>> b2 = bookstore.Book('내가 먹었지롱', '200원', '미니')
책 객체를 새로 만들었어요~

그런대로 쓸 만 하죠? 값이 잘 들어갔는지도 확인해 보세요. 참고로 말씀드리면, 초기화 메서드와 같은 것을 다른 객체지향 언어에서는 생성자(constructor)라고 부른답니다.

 

 

출처: wikidocs

 

 

지금까지 배웠던 내용을 간단하게 실습해봅시다.

 

https://www.mycompiler.io/ko/new/python

 

새 Python 프로그램 만들기 - 마이컴파일러 - myCompiler

실행 코드 코드 저장 기존 코드를 유지하시겠습니까? 에디터에 코드가 있는 동안 언어를 전환하려고 합니다. 이를 유지하려면 “기존 코드 유지”를 선택합니다. 예제로 바꾸려면 “예제로 바

www.mycompiler.io

위 사이트에서는 별도의 파이썬프로그램 설치 없이도 파이썬 코드를 작성하고 실행시켜 볼 수 있습니다.

 

오늘 배운 내용으로 여러분이 마음껏 실습해보세요

 

 

실습 예시)

반응형

'[문법] 파이썬(Python)' 카테고리의 다른 글

[중급] 9강. 파일  (0) 2025.01.06
[중급] 8강. 모듈  (0) 2025.01.06
[기초] 7강. 자료형  (1) 2025.01.06
[기초] 6강. lambda 함수  (0) 2025.01.06
[기초] 5강. 함수  (0) 2024.09.18