티스토리 뷰

반응형

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

객체지향~ 객체지향. 이름은 들어봤지만. 들을 때마다 머리가 아프고, 무슨 말인지 잘 모르겠다!

그래서 일단은. 내가 이해한 만큼 정리해보려고 한다.

우선 이번 포스팅에서는 객체지향이 무엇인가? 에 대해서 작성하고 다음에는 객체지향의 특징 4가지 (상추캐다)! 에 대해서 작성할 것이다.


객체지향의 정의

: 컴퓨터 프로그램을 객체의 모임으로 생각하고, 객체끼리의 상호작용하는 것으로 파악하는 프로그래밍 방법.

무슨 소리인지.. 모르겠다? 가 정상이다. 자 그럼 하나하나씩 들어가보자.

객체에 대해서 먼저 알아보자.

객체는 변수와 함수로 이루어진 것. 더 쉽게 말하자면 정보정보가 하는 행동(함수) 로 이루어진 것들을 모~두 ‘객체’ 라고 부른다.

여기에서 객체를 이루는 틀! 이것을 클래스(class) 라고 부른다.

손흥민 선수 아버지가 그랬다.

“우리 흥민이 절~대 월드 클래스 아닙니다.” 이때의 ‘클래스’. 우리는 ‘클래스’ 가 달라. 할 때의 클래스! 바로 그거다.

음… 대충 알겠어요. 근데 객체고 클래스고 이거 왜 쓰는건데요?

예를 들어, 게임을 만든다고 가정해보자.

이름 : 정뭄뭄 레벨 : 1 경험치 : 0

이렇게 한명의 데이터를 저장한다고 치면. 한명일 때는 괜찮다. 하지만 사람이 많아진다면?

이름 : 정뭄뭄1 레벨 : 1 경험치 : 0 이름 : 정뭄뭄2 레벨 : 1 경험치 : 0

이런 식으로 같은 코드를 여러번 반복해야 하는 상황이 생긴다. 물론! 여러번 작성할 수도 있지만. 그 과정에서 혹~시 오타가 생긴다면? 만약 레벨 이라는 이름을 ‘숙련도’ 라는 이름으로 바꾸고 싶다면?

하나하나 다 바꿔야 하는 불편함이 있지 않을까?

그래서! 이름, 레벨, 경험치라는 ‘틀’ 을 만들어 놓고. 새로운 데이터가 오면 알아서 기존 틀을 가지고 데이터를 북치고 장구치고 요리조리 요리하는거!

→ 이거를 약간 세련되게(?) 표현하자면. 모듈화를 시켜서 각각을 개발한다는 거다.

나중에 수정, 보수에도 유리하기 때문에. 객체지향 프로그래밍을 사용하는 것이다.


Ok.. 나 조금은 알 것 같아요. 근데 그.. 객체 뭐시기 어떻게 쓰는데요?

놀랍게도.. 파이썬을 쓰고 있던 당신. 당신은 이미 객체를 쓰고 있었어요!

예? 그게 무슨 소리에요. 나 오늘 객체지향 처음 들었단 말이에요!!

[1, 2, 3]라는 리스트는 리스트타입(클래스) 의 객체이고

“mummur” 라는 문자열은 문자열타입(클래스)의 객체입니다!!

더욱 엄밀히 말해보자면,

[1, 2, 3]라는 리스트는 리스트타입(클래스)의 인스턴스 입니다. 그러니까, 클래스로 만들어진 객체인스턴스 라고 부르는 거랍니다!

[1, 2, 3] 는 객체이다. (o) [1, 2, 3] 는 리스트타입(클래스)의 인스턴스이다. (o) [1, 2, 3] 는 인스턴스이다. (x)


음… 뭔가 알 듯 말 듯 하죠? 좋아요. 다음으로 가보자구요.

이제 클래스를 직접 만들어 봅시다

class Person:
 pass

class 이름은 대문자로 시작하는게 국룰 이라고 합니다.

자, 클래스를 만들었으니 클래스를 활용한 객체, 즉 인스턴스를 만들어 봅시다.

person1 = Person()

# person1은 Person이라는 class의 인스턴스이다.

얼래? 어디서 본 것 같죠, 꼭 함수를 쓰는 것 같지 않습니까? 익숙한 방식이라 잘 기억이 날 것 같아요.


변수에 대해서 조금 더 알아 볼까요?

아까 객체는 변수와 함수로 이루어 진다고 했었죠!

자 우리는 지금 ‘클래스’와 ‘인스턴스’ 두가지에 대해서 이야기를 했어요. 그러니까! 변수의 종류도 2가지가 나올 수 있겠죠?

아래 예시를 봅시다.

class Person:
    blood_color = 'red' # 클래스 변수 : 공통으로 쓰일변수
    count = 0


    def __init__(self, name): # __init__ 은 생성자 메서드, 인스턴스가 생성할 때 자동으로 호출된다. 이거죠 인스턴스 변수의 정의
        self.name = name
        Person.count += 1
        


person1 = Person('지민') # init에 name 이라는 인자가 있기 때문에, 반드시 이름을 넣어서 변수를 만들어야 한다.
person2 = Person('하림')

print(Person.count) # 2 # 접근 및 할당
print(person1.name) # 지민
print(person1.blood_color) # red
print(person2.blood_color) # red

위 코드를 보면, class 안에 바로 아랫줄에 쓰인 ‘blood_color’ 이 변수를 클래스 변수라고 합니다. (나중에 나오겠지만, 이것은 클래스의 ‘속성’ 이에요) 클래스 변수는 클래스를 이용한 인스턴스라면 모두 공통적으로 가지는 변수에요! 아래 name 이라는 변수는 인스턴스 변수입니다.

쉽게 생각해서 클래스 변수는 공용, 인스턴스 변수는 인스턴스 만이 갖는 특징! 이라고 기억하면 쉽겠네요.


self. name 이요? self 는 자기 자신이랬고… ‘.’ 은 뭔가요?

‘.’ 은 속성 혹은 특징(attribute) 를 나타내기 위해 쓰입니다.

self.<속성명> = <값> 혹은 인스턴스.<속성명> = <값> 으로 쓰여요

여기에서는 self.name = name에서 속성은 ‘name’, 값으로 쓰인 변수명은 ‘name’ 이라고 할 수 있겠어요.

person1 을 출력해보면 오른쪽과 같은 결과가 나옵니다.

print(person1()) # <__main__.Person object at 0x0000029AA2E2A790>

이게 무슨 말일까요? __main__은 파이썬이 실행 될 때 자동으로 실행되는 함수입니다.

main.Person은 python 문서 내에 있는 Person이라는 속성이라는 의미입니다.

마지막으로 숫자는 이 Class의 주소! 박스! 라고 한다네요.

person3 = Person() 처럼 person을 만들때 이름을 안 넣는다면 어떻게 될까요?

생성자 메서드도 함수이기 때문에, init 에는 (name) 이라는 인자가 꼭 들어가야 하기 때문에에러가 발생합니다. 만약에 이름을 안 넣을 경우, 자동으로 ‘홍길동’ 이라고 만들어주려면, 어떻게 하면 될까요?

class Person:

    def __init__(self, name="홍길동"):
        self.name = name
        
        
person1 = Person('지민') 
person2 = Person('하림')
person3 = Person() # 홍길동

print(person3.name)

참고로, Class 변수를 바꿀 때에는 꼭 Class이름.변수명 으로 접근해서 고쳐주세요.

인스턴스이름.변수명 으로 바꾸게 되면 해당하는 인스턴스에서의 특징만 바뀔 뿐!

전체적인 Class 변수는 바뀌지 않거든요.

person1.blood_color = "blue"
print(person1.blood_color) # blue
print(Person.blood_color) #red

Person.blood_color = "black"
print(person1.blood_color) # blue
print(person2.blood_color) # black
print(Person.blood_color) # black

마지막으로 함수에 대해서 더 알아볼게요!

여기까지 오느라 수고했어요. 조금만 더 힘내볼게요!

객체 안에서는 ‘함수’ 라고 부르지 않고 ‘메서드’ (method) 라고 불러요!! 역할은 함수랑 똑같구요.

메서드에는 3가지 종류가 있어요. 인스턴스 메서드, 클래스 메서드, 그리고 정적메서드! 이렇게 있답니다. 일단 큰 틀을 가지고 시작해볼게요.

인스턴스 메서드

class Circle:
    pi = 3.14 # 클래스 변수

    def __init__(self, r):
        self.r = r # 인스턴스 변수

    def area(self):
        return 3.14 * self.r* self.r

    def __str__(self) -> str:
        return f"[원] area : {self.r}"

    def __gt__(self, other):
        return self.r > other.r

c1 = Circle(10)
c2 = Circle(1)

먼저 인스턴스 메서드에요, 위 코드를 잘 봐주세요! 인스턴스 메서드는 인스턴스 변수를 사용하거나, 인스턴스 변수에 값을 설정하는 메서드에요. 호출할 때 첫번째 인자로 인스턴스 자기자신(self) 가 전달되는 것이 특징입니다. 쉽게 생각해서 ‘self’가 들어있다. 하면 모두 인스턴스 메서드라고 생각해도 좋아요!

위에 보이는 __init__는 생성자 메서드로, 인스턴스가 생성될 때 자동으로 호출되는 메서드에요.

이렇게 ‘__’ 로 시작하는 특별한 메서드를 매직메서드, 혹은 던더 라고도 불러요!

인스턴스 메서드를 실행하고 싶을 때에는

인스턴스이름.인스턴스 메서드이름() 을 이용해서 실행합니다.

예를 들어서 area 라는 메서드를 실행하고 싶으면,

print(c1.area()) # 314.0
print(c2.area()) # 3.14

# 만약 self 말고 다른 인자가 있는 인스턴스 메서드라면,
# c2.area() <- 여기의 () 안에 다른 인자를 넣어주셔야 합니다!

클래스 메서드

클래스 메서드는 클래스가 사용할 메서드로, @classmethod라는 데코레이터를 사용해서 정의해요.

인스턴스 메서드에서 첫번째 인자로 (self) 가 호출된 것과 유사하게, 클래스메서드에서는 첫번째 인자로(cls) 가 전달되는 것이 특징이에요.

스테틱 메서드

마지막으로 스테틱 메서드, 혹은 정적메서드는 인스턴트변수, 클래스 변수를 전혀 다루지 않는 메서드에요. 변수를 다루지 않기 때문에! 속성을 다루지 않고, 단지 기능 만을 하는 메서드를 정의할 때 사용해요.

클래스 메서드에 데코레이터가 붙었던 것처럼, 스테틱 메서드는 @staticmethod라는 데코레이터를 사용해요.

마지막으로 예시를 보면서 오늘을 마무리해볼게요.

class Person:
    blood_color = 'red' # 클래스 변수 : 공통으로 쓰일변수
    count = 0


    def __init__(self, name) -> None: # name 은 인스턴스 변수, __init__ 은 생성자함수
        self.name = name
        Person.count += 1
    
    def hello(self):
        print (f"{self.name} 입니다.")

    @classmethod # 클래스 메서드
    def number_of_population(cls): # 첫번째 인자로 cls가 호출된다.
        print(f"인구수는 {cls.count}입니다")

    @staticmethod #스테틱 메서드
    def check_rich(money): # static은 cls, self 사용 x
        return money > 10000

person1 = Person('지민')
person2 = Person('하림')

인스턴스 변수에서 클래스 메서드, 스테틱 메서드를 호출 할 수 있을까요?

print(person1.hello()) # 지민입니다.
print(person1.number_of_population()) # 인구수는 2 입니다.

답은 네! 입니다. 인스턴스 변수에서 클래스 메서드도, 스테틱 메서드도 호출 할 수 있어요. 하지만 인스턴스 변수에서는, 인스턴스 메서드만 쓰세요~ 그게 국룰 이랍니다.

그렇다면! 클래스 변수에서 인스턴스 메서드를 호출할 수 있을까요?

역시 네! 입니다. 아래와 같은 형태로 작성하면 사용할 수 있어요.

print(Person.hello(person1)) # 지민입니다.

하지만! 호출 가능하다고 해서 쓰라는 의미는 아니에요.

print(Person.number_of_population())

클래스 변수에서는 이렇게! 클래스 메서드만 쓰는게 또 국룰랍니다.

여기까지 읽느라 수고했어요. 안녕!


Uploaded by N2T

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함