DevSSOM

파이썬 기초 - 객체지향 프로그래밍 본문

Python/기초

파이썬 기초 - 객체지향 프로그래밍

데브쏨 2021. 6. 10. 23:34
반응형

객체

: 성질 할 수 있는 행동 담은 자료. 지금까지 우리가 배워온 걸로는 성질은 주로 변수, 할 수 있는 행동은 주로 함수로 얘기되어 왔는데, 이 둘을 하나로 합친 자료인 객체라는 애를 만들어냄. 예를 들어서, 객체를 어피치라고 하면

[성질]

이름 : 어피치

나이 : 10대 후반 ~ 20대 초반

성별 : 자웅동체

 

[할 수 있는 행동]

춤추기

울기

웃기

 

클래스(Class)

: 객체를 만들 수 있는 틀. 이모티콘이라면 말이야... 이름, 나이, 성별(성질)이 있어야 하고 엉덩이 흔들기, 모르는척 하기, 땡강부리기(행동)을 할 줄 알아야 돼. 그래서 이 객체를 찍어내는 클래스를 만들기 위해서

 

 class 클래스이름: 으로 생성.

class Emoticon

클래스 안에는 성질과 행동을 담아줘야 하니까

 

필드(Field)

: 객체가 가지고 있는 성질 = 객체가 가지고 있는 변수.

class Emoticon:
    name = "Apeach"
    age = 20         # 10대후반 ~ 20대초반을 평균내서

이렇게 두개의 변수를 추가하게 되면, Emoticon은 두 가지 성질을 가지게 돼. name과 age라는 성질. 이렇게 클래스 안에 변수를 정의해줌으로써 필드를 만들 수 있어.

 

메소드(Method)

: 객체가 할 수 있는 행동 = 객체가 할 수 있는 함수. 이전에 메소드를 짝꿍이 있는 함수라고 했는데, 이 짝꿍이 바로 객체야. 그래서 객체 안에 들어있는 함수를 메소드라고 함.

class Emoticon:
	def dance(self):
    	print("Booty Shake!")

댄스라고 하는 함수를 정의한 뒤, 프린트 엉덩이 흔들기라고 하면, 이모티콘이라고 하는 클래스 안에는 댄스라고 하는 메소드가 생긴거야. 그리고 이 메소드는 이모티콘이 할 수 있는 행동을 의미하게 돼. 이렇게 객체 안에 함수를 정의하게 되면 객체가 할 수 있는 행동을 정의하게 되고, 그게 곧 메소드라는 것.

 

- Self : 메소드라면 가져야하는 첫번째 매개변수. 파이썬에서 메소드를 정의할 때 쓰는 하나의 규약이야. 메소드임을 나타내주기 위해서는 함수를 정의하고 매개변수 안에 셀프를 넣어주는거야. 

 

이제 이 클래스에서 찍어낸 객체가 궁금해. 걔를 인스턴스라고 하는거야.

 

인스턴스(Instance)

: 객체를 만들 수 있는 틀(Class)로 찍어낸 객체. 인스턴스를 만들 땐, 인스턴스 이름 = 클래스 이름()

 apeach = Emoticon()   # 이모티콘 클래스에서 인스턴스 어피치를 찍어내겠다

이모티콘이라는 클래스로 만든 어떤 객체 어피치는 어피치라는 이름과 20살 나이라는 성질 그리고 엉덩이 춤을 출 수 있고, 웃고 울 수 있는 행동을 가지게 돼. 이모티콘이라는 클래스로 어피치 인스턴스를 만드는거야. 그래서 클래스와 인스턴스의 관계는 붕어빵 틀(클래스)과 팥붕어빵, 슈붕어빵(인스턴스)의 관계와 같아. 같은 틀로 팥붕어빵이 나오고 슈붕어빵이 나올 수 있는 것처럼 인스턴스마다 저마다의 특징이 조금씩은 달라질 수 있지만, 그럼에도 여전히 붕어빵 클래스인점은 달라지지 않아.

 

인스턴스의 변수(필드)는 인스턴스.필드

appeach = Emoticon()
apeach.name  # apeach
apeach.age   # 20

인스턴스의 함수(메소드)는 인스턴스.메소드()

apeach = emoticon()
apeach.dance()   # 엉덩이 춤추기!
# 에어컨이 가져야 할 속성 : 희망온도, 바람속도, ...
# 에어컨이 할 수 있는 행동 : 온도 높이기/낮추기, 바람속도 조절, ...

class Aircon:  # Aircon 클래스를 생성
    temp = 20   # 희망온도 변수
    wind_speed = 1   # 바람속도 변수
    
    def wind_speed_up(self): # 바람속도를 증가시키는 함수
    	self.wind_speed = self.wind_speed + 1
        
crystal = Aircon()   # Aircon의 성질을 가진 객체 crystal 생성
print(crystal.temp)   # 20
print(crystal.wind_speed)   # 1

crystal.wind_speed_up()   # 메서드 호출
print(crystal.wind_speed)   # 2

 

 

객체지향 프로그래밍

Q) 왜 객체지향 프로그래밍인가?

: 상속, 다형성, 캡슐화를 통해 코드의 재사용이 쉽고, 우리 실생활을 더 잘 나타낼 수 있기 때문에.

상속

: 한 클래스의 내용을 다른 클래스가 이어받는 것.

 상속을 통해 한 클래스에서 다른 클래스로 핵심 정보를 전달해줄 수 있어. 기존 코드를 재활용하는거지.

class Car:			 
    type = "자동차"
        
class Hyundai(Car):  # 괄호 안에는 상속받을 클래스의 이름을 적어줘
    pass             # 클래스 안에는 아무것도 안적어줄거야
        
sonata = Hyundai()   # 소나타라고 하는 인스턴스는 현대라고 하는 클래스를 이어받았어
print(sonata.type)   # 현대라고 하는 클래스에 아무것도 입력하지 않았는데,
                     # 소나타라고 하는 타입을 이어받은걸 볼 수 있어
                     # 이건 카라고 하는 클래스에서 타입을 정해줬는데,
                     # 현대라고 하는 클래스에서 카를 상속받았기 때문에
                       
class Tree:
    height = 0
    leaf_size = 0
...

class CherryBlossom(Tree):   # Tree의 성질을 그대로 계승!
    height = 25   # 벚꽂나무에 맞게 값을 재조정
    leaf_size = 1

# 마치 부모와 자식처럼 코드를 관리 가능
# 현실 세계의 객체 구조와 유사

다형성

: 같은 모양의 코드가 다른 역할을 하는 것. 그래서 코드를 더 간단하게 만들 수 있어.

class Car:
    type = "자동차"
    horsePower = 100
        
class Lamborghini(Car):
    horsePower = 700
        
aventador = Lamborghini()
print(aventador.type)   # 자동차
print(aventador.horsePower)   # 700

ford = Car()
print(ford.type)   # 자동차
print(ford.horsePower)   # 100

# 이렇게 같은 horsePower임에도 불구하고 어떤 객체냐, 어떤 클래스냐에 따라 값이 달라지게 돼
class CherryBlossom(Tree):
    height = 25
    leaf_size = 1

class Mugunghwa(Tree):
    height = 1
    leaf_size = 5

# 같은 height, leaf_size 변수가 있지만
# class마다 가지는 값이 다르다!
# 같은 이름으로 각 객체의 값을 관리할 수 있음
class Animal:
    legs = 0
    def walk(self):
        return ""

class Dog(Animal):
    legs = 4
    def walk(self):
        return "살랑살랑"

class Human(Animal):
    legs = 2
    def walk(self):
        return "뚜벅뚜벅"

maltese = Dog()
gildong = Human()

print(maltese.walk())   # 살랑살랑  
print(gildong.walk())   # 뚜벅뚜벅   # 같은 walk 메소드라고 해도 어떤 클래스였냐에 따라 출력이 달라

 

캡슐화

: 보기 쉽게 코드를 묶어서 정리할 수 있음. 정보 은닉해서 사적인 정보들을 잘 숨길 수도 있어.

 

 

 

Q) 객체지향 프로그래밍으로 하면 뭐가 다른가?

ex) 포켓몬 게임에서 치코리타가 구구에게 '울음소리' 기술로 10의 데미지를 입혔다 -> 이걸 우리가 지금까지 배운 내용으로 구현할 수 있을까? No. 하지만 이런 상황에서 객체지향 프로그래밍을 사용한다면 문제를 조금 더 쉽게 해결할 수 있어. 

 

포켓몬 클래스 생성

    - 포켓몬이라면 가져야할 특징은? 이름, 체력, 타입 등

    - 포켓몬이라면 할 수 있는 능력은? 각 포켓몬의 기술

이렇게 포켓몬을 필드와 행동으로 나눠서 생각할 수 있으니까 아래와 같이 클래스를 정의할 수 있어

class Pocketmon:
	p_name = ""
    p_hp = 0
    p_type = ""
    def skill(self):
    	pass

피카츄 클래스를 생성해보면, (포켓몬 클래스를 상속하는 피카츄 클래스 생성)

    - 피카츄의 특징은? 이름 피카츄, 성비 5:5, 체력은 50이고, 전기 속성이다

    - 피카츄의 능력은? 백만 볼트

class Pikachu(Pocketmon):
	p_name = "Pikachu"
    p_hp = 50
    p_type = "Electric"
    def skill(self):
    	print("백만 볼트!")

피카츄 인스턴스 생성

피카츄 클래스로 찍어 낸 pika 인스턴스

pika = Pikachu()
pika.skill()   # 백만 볼트!
print(pika.p_hp)   # 50

 

파이썬에서의 객체

파이썬에서는 객체 단위로 정보를 관리함. 숫자형자료 1 2 3, 문자열자료 'abc', 리스트 자료 [1, 2, 3] 얘네 하나하나가 모두가 객체에 해당. 이들의 자료형이었던 int, str, list 등등은 이 자료형의 클래스야. 그리고 이들이 객체이기 때문에, 다음과 같은 속성을 가지고 있음.

  • 값(Value) : 객체에 담긴 내용
  • 유형(Type) : 객체의 종류
nums = [1, 2, 3]

print(nums)   # [1, 2, 3] 이게 객체의 값
print(type(nums))   # <class 'list'>  nums의 클래스는 리스트

# 리스트가 객체니까 이 리스트에 딸려있는 함수, 즉 메소드를 쓸 수 있어
# 우리가 리스트나 숫자나 딕셔너리에 메소드를 사용할 수 있었던 이유가
# 파이썬이 자료를 객체로 저장하기 때문이야
# 그래서 객체들 = 자료들은 값과 유형을 가지고 있다는 것

nums.append(4)
print(nums)   # [1, 2, 3, 4]

 

 

 

연습문제

# 클래스 Bbread(붕어빵)을 만들어봅시다.
# Bbread의 필드 taste를 생성하고, "밀가루"를 대입해봅시다.
# Bbread의 메서드 eat()를 생성해봅시다. 이 메서드는 taste, "맛이 나요!"를 출력합니다.
# taste의 값이 "밀가루"라면 "밀가루 맛이 나요!" 가 출력됩니다.
class Bbread:
    taste = "밀가루"
    def eat(self):
        print(self.taste, "맛이 나요!")

# 클래스 Bbread의 인스턴스 redBean과 choux를 만들어봅시다.
redBean = Bbread()
choux = Bbread()


# 객체 redBean의 필드 taste를 "팥"으로 바꿔줍시다
redBean.taste = "팥"

# 객체 choux의 필드 taste를 "슈크림"으로 바꿔줍시다
choux.taste = "슈크림"

# 객체 redBean의 메서드 eat()를 실행해봅시다
redBean.eat()   # 팥 맛이 나요!

# 객체 choux의 메서드 eat()를 실행해봅시다
choux.eat()   # 슈크림 맛이 나요!

 

728x90
반응형
댓글