파이썬 class
클래스(class): 구조, 설계도, 틀; 만들고자 하는 객체의 속성과 메서드의 집합
객체(object): 클래스로부터 만들어진 결과물, 클래스로 선언된 변수
인스턴스(instance): 객체가 메모리에 할당된 상태; 클래스로 정의된 객체를 프로그램 상에서 이용할 수 있게 만든 변수
예) 붕어빵 틀(class), 붕어빵(object)
Super class
Sub class(== Child class)
생성자(Constructor)
init() 메서드
클래스 변수
메서드(Method)
속성
메서드 오버라이딩(Method Overriding)
기본형
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
==================================================================
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 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세 입니다."
==================================================================
만들어둔 클래스 원본을 건드리지 않고, 원본을 기반(원본을 상속 받고)으로 업데이트 버전을 새로 만들고자 할 때 사용
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세 입니다."
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세 입니다."