본문 바로가기

Programming/Python

객체 지향 프로그래밍 ( Object - Oriented Programming )

객체 지향 프로그래밍


지금까지 프로그램을 작성할 때 ,  우리는 데이터를 다루는 명령들의 블록함수들의 조합으로 프로그램을 구성하였다.

이러한 설계 방식을 절차 지향 프로그래밍 기법이라고 부른다.

이와달리 데이터와 기능을 객체라고 불리는 것으로 묶어서 프로그램을 구성하는 또 다른 기법이 있다.
대부분의 시간동안 절차 지향 프로그래밍 기법을 통해 프로그램을 작성하게 되겠지만 , 
큰 프로그램 , 복잡한 프로그램등을 작성할 때나 이 기법을 이용하는 것이 더 편리한 문제를 해결해야 할 경우 
객체 지향 프로그래밍 기법을 활용할 수 있다.

객체 지향 프로그래밍 기법에는 클래스객체라는 두 가지 주인공이 있다.

클래스새로운 형식을 정의하는 것이며 , 객체클래스의 인스턴스를 의미한다.

이것을 다시 표현하면 우리가 int 라는 형식의 변수를 만들 수 있다는 것으로 , 이것은 곧 정수형을 저장하는 변수는 
int 클래스의 인스턴스(객체)를 변수에 할당하는 것 이라고도 말할 수 있다.

( 파이썬에서는 정수형조차도 객체로 다루어진다.    (int 클래스의 객체) )

객체는 그 객체에 내장된 일반적인 변수들을 사용하여 데이터를 저장할 수 있다.
이때 개체 혹은 클래스에 소속된 변수들을 필드(Field) 라고 부른다.


객체는 또한 내장된 함수를 이용하여 어떤 기능을 갖도록 할 수 있는데 , 이것을 클래스의 메소드(Method) 라고 부른다.

이러한 명칭을 구별하여 부르는것이 중요한데 , 이는 일반적인 변수와 함수와 달리 이들은 클래스나 객체에 소속되어 있는 대상들이기 때문이다.
또 , 이러한 필드와 메소드들을 통틀어 클래스의 속성(Attribute) 이라고 부른다.


필드는 크게 두가지 종류가 있다 , 하나는 클래스의 인스턴스/객체에 내장되어 있는것이고 , 또 하나는 클래스 자체에 내장되어 있는 것이다.
각각을 인스턴스 변수클래스 변수라 부른다.
( 인스턴스 변수 : 클래스의 인스턴스 /  객체에 내장되엉 있는 변수 ,  클래스 변수 : 클래스 자체에 내장되어 있는 변수 )

클래스는 class 키워드를 통해 생성되며 클래스의 필드와 메소든느 그 아래 들여쓰기 된 블록에 차례로 정의된다.


self에 대하여

클래스 메소드는 일반적인 함수와 다른점이 있다.
그것은 메소드의 경우 매개변수의 목록에 항상 추가로 한개의 변수가 맨 앞에 추가되어야 한다는 점이다.

또한 메소드를 호출할 떄 이 변수에는 우리가 직접 값을 넘겨주지 않으며 , 대신 파이썬이 자동으로 값을 할당한다.
이 변수에는 현재 객체 자신의 참조가 할당되며 , 일반적으로 self 라 이름짓는다.


변수의 이름은 마음대로 지을수 있지만 , self 라는 이름을 사용하자 .
이것은 일종의 약속이며 다른 이름을 사용하는 것은 여러모로 불편함을 겪을 것이다.
'self'라는 표준적인 이름을 사용하면 우리의 프로그램을 읽는 사람들로부터 이것이 바로 그 변수 ( 클래스 메소드의 첫 매개변수) 임을 쉽게 알아보게 할 수 있고 , 특별한 IDE (Intergrated Development Environment)를 사용하는 사람들도 이를 쉽게 알아볼 수 있는 등 여러 장점이 있다.

파이썬이 self에 어떻게 값을 할당하는 것인지 그리고 정말 값을 직접 할당한 필요가 없는지 궁금할 것이다.
이해를 돕기위해 예를 하나 들어보자!
우리가 Myclass 라는 클래스를 생성했고 , 이 클래스의 객체를  myobject 라는 이름으로 생성했다고 해보자.
이제 이 객체의 메소드를 호출할 때는 myobject.method(arg1 , arg2)와 같이 하며 , 
이것은 파이썬에 의해 자동적으로 Myclass.method(myobject, arg1, arg2) 의 형태로 바뀌게 된다.
이것이 self의 모든것이다.

또한 이것은 아무런 인수도 넘겨받지 않는 메소드를 정의할 때도 , self 라는 하나의 인수를 추가해 주어야한다는걸 의미한다.


클래스

이해하기 쉽도록 간단한 클래스의 예시를 하나 들어보자.

class Person:
pass # An empty block

p = Person()
print(p)

실행 결과 : 

   <__main__.Person object at 0x014EB470>




class문을 사용하여 새로운 클래스 (Person)을 생성하였다.
그 아래로는 들여쓰기 된 새로운 블록이 시작되며 이 블록은 클래스의 몸체를 구성한다.
위 코드에서는 pass문으로 해당 블록이 빈 블록임을 나타냈다.

다음으로 , 이 클래스의 이름 뒤에 괄호를 열고 닫아주어 클래스의 객체/인스턴스를 만들었다.
(객체 초기화에 대해서는 추후에 정리하겠다.)        
객체가 잘 생성되었는지 확인하기 위해 , 정의한 변수명을 입력하여 결과를 확인해본다.
그러면 이 객체는 main모듈의 Person 클래스의 인스턴스임을 알 수 있다.


메소드

앞서 , 클래스 / 객체는 메소드를 가질 수 있으며 , 메소드는 추가된 self 변수를 제외하고 함수와 똑같다는 것에 대해 얘기헀다.

아래는 예제다.


class Person:
def say_hi(self):
print("Hello, How are you?")

p=Person()
p.say_hi()


실행 결과:

Hello, How are you?


위 예제는 self가 어떻게 동작하는지 보여준다.
여기서 say_hi메소드는 아무 매개변수도 넘겨받지 않지만 함수 정의에 self를 가지고 있다!



init 메소드
파이썬의 클래스에는 여러가지 특별한 메소드 이름이 존재한다.
우선 그 중 init 메소드에 대해 알아보자.
init 메소드는 클래스가 인스턴스화 될 때 호출된다.
따라서 , 이 메소드는 객체가 생성될 때 여러가지 초기화 명령들이 필요할 때 유용하게 사용된다.
여기서 init의 앞과 뒤에 있는 언더바는 두번씩 입력해야한다.

class Person:
def __init__(self,name):
self.name = name
def say_hi(self):
print("Hello, my name is",self.name)

p = Person("Swaroop")
p.say_hi()

실행 결과 :
                Hello, my name is Swaroop


먼저 매개변수 name을 넘겨받는 init 메소드를 정의한다.    (물론 self를 포함하여 정의한다.)

그리고 , name이라는 필드를 생성한다.
이때 두 다른 변수의 이름으로 name 이라는 동일한 이름을 지정해주었음을 주목하자.
이것이 문제가 되지 않는 이유는 하나는 "self"라는 개체에 내장된 것으로써 self.name의 형태로 사용되며
또 하나는 name은 지역 변수를 의미하는 것으로 사용되기 때문이다.
프로그램 상에서 완전히 구분이 가능하기 때문에 혼란이 일어나지 않는다.


위 예제에서 가장 중요한건 , 우리가 init 메소드를 직접 호출해주지 않고 클래스로부터 인스턴스를 생성할 때 괄호 안에 인수 ( "Swaroop" ) 를 함께 넘겨주었다는 점이다.
이 점이 이 메소드가 특별히 다뤄지는 이유다.

이제 , say_hi메소드에서 처럼 객체 내부에서 self.name 필드를 사용할 수 있다.

'Programming > Python' 카테고리의 다른 글

상속  (0) 2017.11.13
클래스 변수와 객체 변수  (0) 2017.11.13
문자열 보충설명  (0) 2017.11.11
집합 그리고 참조  (0) 2017.11.11
열거형  (0) 2017.11.11