15. 객체 지향 프로그래밍#

객체 지향 프로그래밍Object-Oriented Programming은 객체들 사이의 유기적인 관계를 묘사하는 프로그래밍 기법이며, 줄여서 보통 OOP라고 부른다. 파이썬, 자바, C++, C#, 루비, 자바스크립트 등 대부분의 프로그래밍 언어가 OOP를 지원하는 객체 지향 언어다.

OOP와 대비되는 개념으로 절차 지향 프로그래밍이 있다. 절차 지향 프로그래밍은 수행해야 할 일을 순차적으로 처리하는 과정을 묘사하는 것을 가장 중요하게 여기며 프로그램 전체가 유기적으로 연결되도록 만드는 프로그래밍 기법이다. C, HTML 등이 대표적인 절차 지향 프로그래밍언어다.

“해야 할 일을 순차적으로 처리한다”는 표현은 가장 기초적인 프로그래밍 기법이며, 모든 프로그램은 원하는 결과를 얻기 위한 과정을 논리적이며 순차적으로 처리하도록 구현되어야 한다. OOP 역시 예외가 아니다. OOP는 다만 구현해야 할 객체들을 선택하고 객체들 사이의 유기적인 관계를 이용하는 과정을 논리적으로 묘사하는 데에 보다 많은 방점을 둘 뿐이다.

15.1. OOP와 객체#

OOP를 이해하려면 아래 두 가지 질문에 답할 수 있어야 한다.

  1. 객체(object)란 무엇인가?

  2. “객체를 중심으로 프로그래밍한다” 라는 말의 의미는 무엇인가?

위 질문들에 대한 직접적인 설명 대신에 turtle 모듈의 거북이 그래픽에 포함되는 다양한 객체들을 이용하여 객체가 생성되고 활용되는 과정을 다양한 예제를 통해 소개한다.

준비사항

turtle 모듈을 사용하기에 구글 코랩은 매우 제한적이다. 9장에서 활용한 트링킷이 거북이 그래픽을 지원하지만 여기서는 레플릿 사이트를 활용한다. 이유는 트링킷에서는 turtle 모듈의 모든 것을 지원하지는 않고 대신 거북이 그래픽 코딩을 간편하게 테스트하는 용도로 만들어졌기 때문이다. 여기서 사용하는 코드는 모두 레플릿에서 확인하고 직접 실행할 수 있도록 링크가 함께 제공된다.

15.2. 거북이 그래픽#

거북이 그래픽은 파이썬의 기본 라이브러리로 포함된 turtle 모듈을 이용한다. 거북이 그래픽과 turtle 모듈에 대한 상세한 설명은 9장을 참고한다. 여기서는 간단한 예제를 통해 객체(인스턴스)를 클래스의 인스턴스로 선언하고 활용하는 과정을 소개한다.

아래 코드를 실행하면 한 변의 길이가 100인 정사각형을 그리는 화살촉의 움직임을 볼 수 있다.

참고: (레플릿) 네모에서 코드 실행 가능

import turtle

wn = turtle.Screen()
wn.title("Hello, Bob and Alice!")

bob = turtle.Turtle()

for _ in range(4):
    bob.forward(100)
    bob.left(90)

wn.mainloop()

위 코드의 구성 요소를 객체를 중심으로 살펴 보면 다음과 같다.

모듈 불러오기

turtle 모듈은 거북이 그랙픽에 필요한 다양한 클래스와 함수를 제공한다.

import turtle

스크린 객체: Screen 클래스의 인스턴스

turtle 모듈에서 정의된 Screen 클래스의 인스턴스를 생성해서 wn 변수에 할당한다. Screen 클래스의 인스턴스는 그림을 그릴 도화지 한 장에 해당하는 객체다.

wn = turtle.Screen()

스크린 객체 메서드

스크린 객체의 타이틀을 지정할 수 있다. 기본값은 Python Turtle Graphics이지만 title() 메서드를 이용하여 별도로 지정할 수 있다.

wn.title("Hello, Bob and Alice!")

반면에 아래 mainloop() 메서드는 도화지가 X 버튼이 눌릴 때까지 사라지지 않도록 한다.

wn.mainloop()

거북이 객체: Turtle 클래스의 인스턴스

turtle 모듈에서 정의된 Turtle 클래스의 인스턴스를 하나 생성해서 bob 변수에 할당한다. Turtle 클래스의 인스턴스는 아래 그림의 화살촉 모양처럼 선을 그리는 펜 역할을 수행하는 객체에 해당한다.

bob = turtle.Turtle()

거북이 객체 메서드

거북이 객체의 forward() 메서드는 펜이 가리 가리키는 방향으로 이동하면서 선을 그리도록 한다. 아래 코드는 100만큼 전진시키면서 선을 긋도록 한다.

bob.forward(100)

거북이 객체의 left() 메서드는 또한 펜이 가리키는 방향을 기준으로 반시계 방향으로 지정된 각도만큼 회전시킨다. 아래 코드는 펜이 가리키는 방향을 90도 반시계 방향으로 회전시킨다. 단 이동은 하지 않는다.

bob.left(90)

사각형을 그리기 위해 거북이 객체가 전진과 회전을 총 4번 반복하도록 한다.

for _ in range(4):
    bob.forward(100)
    bob.left(90)

거북이 객체의 보다 다양한 메서드에 대해서는 9장을 참고한다.

15.3. 객체의 독립성#

클래스의 인스턴스로 생성된 객체들은 기본적으로 상호 독립적이다. 하지만 두 객체 사이의 상호 교감이 가능한 경우도 있다. 객체 지향 프로그래밍은 객체 각각이 수행하는 기능과 객체들 사이의 교감을 활용하는 프로그램 기법을 의미한다.

여기서는 거북이 객체를 두 개를 상호 독립적으로 활용하는 방법을 소개한다. 객체들 사이의 교감을 구현하는 방식은 16장에서 다룬다.

예제 1

아래 코드를 실행하면 두 개의 거북이 객체에 의해 검정 사각형 빨강 삼각형이 도화지 위에 그려진다.

참고: (레플릿) 네모-세모에서 코드 실행 가능

import turtle

wn = turtle.Screen()
wn.title("Hello, Bob and Alice!")

# bob 으로 사각형 그리기
bob = turtle.Turtle()

for _ in range(4):
    bob.forward(100)
    bob.left(90)

# alice로 삼각형 그리기
alice = turtle.Turtle()

alice.shape("turtle")
alice.color("red")

alice.penup()
alice.backward(100)
alice.pendown()

for _ in range(3):
    alice.forward(100)
    alice.right(120) 

wn.mainloop()

위 코드에서 bobalice 모두 Turtle 클래스의 인스턴스를 가리킨다. alice가 가리키는 거북이 객체는 bob의 경우와 다르게 다음 두 메서드에 의해 빨강 거북이로 변형된 후에 시계 방향으로 회전하면서 삼각형을 그린다.

  • shape() 메서드: 거북이 객체의 모양 지정

  • color() 메서드: 거북이 객체의 색 지정. 이동할 때 그려지는 선의 색도 함께 변경됨

  • right() 메서드: 거북이 객체가 바라보는 방향을 기준으로 시계 방향으로 지정된 각도만큼 회전

예제 2

아래 코드를 실행하면 두 개의 거북이 객체에 의해 파랑 회오리와 빨강 회오리가 그려진다. 새로이 사용된 메서드는 다음과 같다.

  • bgcolor(): 스크린 객체인 도화지의 바탕화면 색 지정

  • penup(): 거북이 객체의 선 그리기 기능 해제

  • stamp(): 거북이 객체의 모양 도장 찍기

참고: (레플릿) 도장찍기에서 코드 실행 가능

import turtle

wn = turtle.Screen()
wn.bgcolor("lightyellow")

colors = ['blue', 'red']

for i in range(2):
    step = 20
    angle = 40

    t = turtle.Turtle()
    t.shape("turtle")
    t.color(colors[i])
    t.penup()

    t.forward(step * i)
    for _ in range(26):
       t.stamp() 
       step = step + 5
       t.forward(step) 
       t.right(angle)
    
wn.mainloop()

15.4. 필수 예제#

참고: (필수 예제) 객체 지향 프로그래밍

15.5. 연습문제#

참고: (연습) 객체 지향 프로그래밍