[Python] Class 클래스

Jae Gyeong Lee·2024년 3월 13일

파이썬 class

클래스(class): 구조, 설계도, 틀; 만들고자 하는 객체의 속성과 메서드의 집합
객체(object): 클래스로부터 만들어진 결과물, 클래스로 선언된 변수
인스턴스(instance): 객체가 메모리에 할당된 상태; 클래스로 정의된 객체를 프로그램 상에서 이용할 수 있게 만든 변수

예) 붕어빵 틀(class), 붕어빵(object)

0. 주요 용어

Super class

  • 모태가 되는 클래스

Sub class(== Child class)

  • 모태가 되는 클래스로부터 상속 받은 클래스

생성자(Constructor)

  • 객체를 만들 때 실행되는 함수

init() 메서드

  • 클래스 생성자 메서드

클래스 변수

  • 클래스에서 공유되는 변수

메서드(Method)

  • 클래스 안에서 정의된 함수

속성

  • 클래스 안에서 정의된 변수

메서드 오버라이딩(Method Overriding)

  • 상속 받은 메서드를 재정의

1. 클래스 생성 방법

기본형

class Person:                    # 1) 클래스 이름 정의

    total_count = 0              # 2) 클래스 변수, 클래스 사이에서 공유되는 변수

    def __init__(self):          # 3) 생성자 메서드, 클래스로부터 객체가 만들어질 때 호출되는 함수; self는 클래스로부터 만들어진 객체 자신
        self.name = '홍길동'               # 인스턴스 변수, 자기 자신(self)의 name 지정
        self.age = 1                      # 인스턴스 변수, 자기 자신(self)의 age 지정
        Person.total_count += 1           # 클래스 변수(total_count)에 접근할 땐, {정의된 class의 이름}.{클래스 변수명}
        
    # 인스턴스 변수에 접근할 땐 self.{변수명}
    # 클래스 변수에 접근할 땐 {정의된 class의 이름}.{클래스 변수명}
 
    def introduce(self):        # 4) 메서드, 사용자가 원하는 로직 구현
        print(f'제 이름은 {self.name}이고, 나이는 {self.age}살 입니다.')

init 함수에 인자 추가

class Person:                    

    total_count = 0              

    def __init__(self, name, age):        # 사용자가 객체 생성 시 Arguments(함수 인자)로 name, age 값을 받음
        self.name = name
        self.age = age
        Person.total_count += 1           
        
    def introduce(self):       
        print(f'제 이름은 {self.name}이고, 나이는 {self.age}살 입니다.')

p1 = Person('김철수', 22)  #  객체 = 클래스()
p1.introduce() # 객체.메서드() ; 사용자가 정의한 메서드 호출
-> "제 이름은 김철수이고, 나이는 22살 입니다."

상속(inheritance)

#super class1
class Person:                    
    total_count = 0              
    def __init__(self):
        self.name = '홍길동'
        self.age = 1
        Person.total_count += 1           
    def introduce(self):       
        print(f'제 이름은 {self.name}이고, 나이는 {self.age}살 입니다.')

#sub class1
class Student(Person):   # Student 클래스(sub class)는 Person 클래스(super class)를 상속 받아 만든 클래스
    def __init__(self):
        super().__init__()  # super class (Person)가 갖고 있는 __init__ 함수를 가져오겠다

student = Student()
student.introduce()   # Student 클래스 안에 introduce 함수를 구현하지 않아도 사용 가능, super class가 갖고 있는 __init__ 함수 외의 것들도 상속
-> "제 이름은 홍길동이고, 나이는 1살 입니다."    
#super class2
class Person:                    
    total_count = 0              
    def __init__(self, name, age):
        self.name = name
        self.age = age
        Person.total_count += 1           
    def introduce(self):       
        print(f'제 이름은 {self.name}이고, 나이는 {self.age}살 입니다.')


#sub class2
class Student(Person):
    def __init__(self):
        super().__init__()

s1 = Student()
-> 에러, missing positional arguments


#sub class2 수정; 단점: 아래와 같이 하면, 홍길동, 1이 고정되서 객체가 생성됨
class Student(Person):
    def __init__(self):
        super().__init__('홍길동', 1)

s1 = Student()
s1.introduce()
-> "제 이름은 홍길동이고, 나이는 1살 입니다."


#sub class2 수정2
class Student(Person):
    def __init__(self, name, age):
        super().__init__(name, age)

s1 = Student('홍길동', 1)
s1.introduce()
-> "제 이름은 홍길동이고, 나이는 1살 입니다."

s2 = Student('홍길동', 2)
s2.introduce()
-> "제 이름은 홍길동이고, 나이는 2살 입니다."

상속 시, 유념해야 할 것: 클래스 오버라이딩

#super class
class Person:                    

    def __init__(self, name='홍길동', age=20):
        self.name = name
        self.age = age        
        
    def introduce(self):       
        print(f'난 Percon 이름은 {self.name}이고, 나이는 {self.age}살 입니다.')

#sub class
class Student(Person):

    def __init__(self):
        super().__init__()
        
    def introduce(self):
        #super().introduce() # 주석을 풀어줄 경우, super class에 있는 introduce 메서드 호출
        print(f'난 Student 이름은 {self.name}이고, 나이는 {self.age}살 입니다.') # sub class에 있는 introduce 메서드 로직 실행


# super class를 상속 받은 sub class에 super class와 동일한 메서드(introduce)가 있는 경우,
# sub class에 있는 메서드(introduce)가 호출됨, super().introduce()는 sub class에 있는 메서드(introduce) 안으로 super class의 메서드(introduce)를 불러와 실행하는 것

상속 구조 확인

{클래스이름}.mro()
Student.mro()
-> [main.Student, mainPerson, object] # Student 클래스는 Person 클래스를 상속 받았다.

//////////

클래스 변수

Person.total_count += 1 # Person class를 1번 만들 때, 마다 1씩 올라감.

p1 = Person()
p2 = Person()
p3 = Person()

p3.class.total_count
-> 3

==================================================================

  1. init # initiate, 클래스를 선언하는 순간 바로 실행되는 함수

class test:
def init(self): # initiate, 클래스를 선언하는 순간 바로 실행되는 함수
print("test 클래스 선언")
def func(self):
print("func 실행")

a = test() # test 클래스를 만들고 a에 할당, 동시에 init 함수 안의 내용이 바로 실행됨
-> "test 선언" # init 함수 안에 있는 내용만 실행됨

a.func()
-> "func 실행" # init 외 함수는 만들어진 클래스 변수(a) 뒤에 ' .함수() '를 붙여야 됨

  • 해당 class에서 반드시 필요한 내용이 ' init 함수 ' 안에 포함되어야 함
  • 일반적으로 함수를 만들 때, 입력 변수가 없으면 괄호 안(())을 비워야 하지만, class에서는 self를 넣어줘야 함.

==================================================================

  1. self # self, 클래스를 저장할 변수

class JSS:
def init(self): # initiate, 클래스를 선언하는 순간 바로 실행되는 함수
self.name = input("이름: ")
self.age = input("나이: ")
def show(self): # 만들어진 클래스 변수(a) 뒤에 ' .함수() '를 붙여야 실행되는 함수
print("나의 이름은 {}. 나이는 {}세 입니다.".format(self.name, self.age))

a = JSS()

JSS 클래스 코드 안에 포함된 'self'는 JSS 클래스를 할당한 변수 a에 해당, 즉 self = a

a = JSS() # init 함수 안에 있는 내용이 실행됨
-> 이름: 홍길동 # input("이름: ") → '홍길동'입력
-> 나이: 28 # input("나이: ") → '28' 입력

a.name # == self.name
-> 홍길동

a.age # == self.age
-> 28

a.show() # def show(self) 에서 self(== a)가 앞으로 빠져 나왔기 때문에 self.show() → a.show(), 괄호안이 빈 값
-> "나의 이름은 홍길동. 나이는 28세 입니다."

==================================================================

  1. super # 클래스 상속

만들어둔 클래스 원본을 건드리지 않고, 원본을 기반(원본을 상속 받고)으로 업데이트 버전을 새로 만들고자 할 때 사용

원본

class JSS:
def init(self): # initiate, 클래스를 선언하는 순간 바로 실행되는 함수
self.name = input("이름: ")
self.age = input("나이: ")
def show(self): # 만들어진 클래스 변수(a) 뒤에 ' .함수() '를 붙여야 실행되는 함수
print("나의 이름은 {}. 나이는 {}세 입니다.".format(self.name, self.age))

업데이트 버전

class JSS2(JSS): # 상속 받는 클래스(JSS)를 인자로 넣어줌
def init(self):
super().init() # JSS클래스 init 함수 내용을 그대로 가져옴
'''
즉 아래 내용이 포함되어 있는 것
self.name = input("이름: ")
self.age = input("나이: ")
'''

                       # super() 이 부분은 상속 받은 클래스(JSS)를 의미
                       
    self.gender = input("성별: ") # 업데이트할 내용 추가

b = JSS2() # init 함수 안에 있는 내용이 실행됨
-> 이름: 홍길동 # input("이름: ") → '홍길동'입력
-> 나이: 28 # input("나이: ") → '28' 입력
-> 성별: 남 # input("성별: ") → '남' 입력

b.show() # JSS2 클래스엔 show() 함수를 추가하지 않았지만, JSS를 상속받고 있기 때문에 JSS에 있는 show() 함수를 그대로 가져온 것.
-> "나의 이름은 홍길동. 나이는 28세 입니다."

  • JSS에 있는 show() 함수는 아래와 같기 때문에, 새로 input으로 넣어준 '남' 값이 같이 출력되진 않은 것
    def show(self): # 만들어진 클래스 변수(a) 뒤에 ' .함수() '를 붙여야 실행되는 함수
    print("나의 이름은 {}. 나이는 {}세 입니다.".format(self.name, self.age))
  • show() 함수 출력 값을 바꿔주려면, 아래와 같이 JSS2클래스에 show()함수를 생성

class JSS2(JSS): # 상속 받는 클래스(JSS)를 인자로 넣어줌
def init(self):
super().init() # JSS클래스 init 함수 내용을 그대로 가져옴
self.gender = input("성별: ") # 업데이트할 내용 추가
def show(self): # 만들어진 클래스 변수(a) 뒤에 ' .함수() '를 붙여야 실행되는 함수
print("나의 이름은 {}. 성별은 {}자, 나이는 {}세 입니다.".format(self.name, self.gender, self.age))

b.show()
-> "나의 이름은 홍길동. 성별은 남자, 나이는 28세 입니다."

profile
안녕하세요 반갑습니다. 공부한 내용들을 기록하고 있습니다.

0개의 댓글