클래스(Class)는 객체를 생성하기 위한 설계도 혹은 틀이며, 객체 지향 프로그래밍의 기본적인 개념 중 하나입니다. 하나의 설계도를 통해서 동일한 결과를 계속 만들어 낼 수 있으므로, 코드의 재사용성
과 확장성
을 높일 수 있습니다.
클래스는 class
키워드를 사용하여 정의할 수 있으며, 다음과 같은 형식으로 정의할 수 있습니다.
class ClassName:
# class variable
class_var = 10
# Constructor
def __init__(self, args):
# instance variable
self.instance_var = args
# instance method
def instance_method(self, args):
# TODO
# class method
@classmethod
def class_method(cls, args):
# TODO
# static method
@staticmethod
def static_method(args):
# TODO
객체를 생성하면 해당 클래스의 인스턴스(instance)
가 생성됩니다. 객체가 생성되면 해당 클래스의 모든 속성을 상속하게 됩니다.
myclass = ClassName(10)
클래스 변수나 인스턴스 변수의 이름 앞에 __
가 붙으면 클래스 내부에서만 사용할 수 있는 변수가 됩니다.
class MyClass:
__private_class_var = 10
def __init__(self):
self.__private_instance_var = 3
def sum(self) -> int:
return MyClass.__private_class_var + self.__private_instance_var
myclass1 = MyClass()
print(myclass1.sum()) # 13
다음과 같이 클래스 외부에서 접근하면 AttributeError
가 발생합니다.
print(myclass1.__private_class_var)
print(myclass1.__private_instance_var)
메서드(Method)는 클래스에 속한 함수
입니다. 하지만 메서드의 종류에 따라 클래스 내의 데이터에 대한 접근 권한이 다르게 적용됩니다.
초기 값
을 설정해야 할 필요가 있을 때는 생성자(constructor)를 이용하여 설정할 수 있습니다. 메서드의 함수 이름이 __init__
이면 생성자로 취급됩니다.
class MyClass:
def __init__(self, a:int):
self.a = a
myclass1 = MyClass(a=10)
myclass2 = MyClass(a=20)
print(myclass1.a) # 10
print(myclass2.a) # 20
객체들을 다른 초기 값으로 설정할 수 있다면 객체들을 생성할 때 공통으로 같은 값을 설정하고 싶다면 클래스 변수를 사용할 수 있습니다.
class MyClass:
b = 5
def __init__(self, a:int):
self.a = a
myclass1 = MyClass(a=10)
myclass2 = MyClass(a=20)
print(myclass1.a, myclass1.b) # 10 5
print(myclass2.a, myclass2.b) # 20 5
💡 생성자에서 클래스 변수에 접근하려면 MyClass.b와 같이 클래스 명.클래스 변수 명으로 접근할 수 있습니다.
클래스의 인스턴스 변수
에 접근이 가능하며, 인자의 첫 번째는 항상 self
로 시작됩니다.
다음의 예시에서는 메서드의 인자의 개수는 2개인데, 클래스 객체가 인스턴스 메서드를 호출 시 1개의 인자를 전달하고 있습니다.
class MyClass:
def __init__(self, b:int):
self.b = b
def instance_method(self, c:int) -> int:
return self.b + c
myclass1 = MyClass(b=10)
print(myclass1.instance_method(5)) # 15
myclass1이 self로 인식되기 때문에 1개의 인자만 전달하여도 됩니다. 2개의 인자를 전달할 때는 다음과 같이 사용할 수 있습니다.
class MyClass:
def __init__(self, b:int):
self.b = b
def instance_method(self, c:int) -> int:
return self.b + c
myclass1 = MyClass(b=10)
print(MyClass.instance_method(myclass1, 5)) # 15
💡 인스턴스 메서드에서 클래스 변수에 접근하려면 MyClass.b와 같이 클래스 명.클래스 변수 명으로 접근할 수 있습니다.
클래스의 클래스 변수
에 접근이 가능하며, 인자의 첫 번째는 항상 클래스 자신인 cls
로 시작됩니다. 또한, 인스턴스를 만들지 않고도 호출할 수 있다는 특징이 있습니다.
클래스 메서드를 정의하려면 다음과 같이 @classmethod
데코레이터를 사용합니다.
class MyClass:
a = 10
@classmethod
def class_method(cls, c:int) -> int:
return cls.a + c
myclass1 = MyClass()
print(myclass1.class_method(5)) # 15
# 인스턴스 생성 없이 바로 호출
print(MyClass().class_method(5)) # 15
💡 클래스 메서드는 인스턴스 메서드에 접근할 수 없습니다.
클래스나 인스턴스에 관련이 없는
함수를 정의할 때 유용합니다. 인스턴스 메서드나 클래스 메서드처럼 함수의 첫 번째 인자에 self나 cls를 사용하지 않습니다. 또한, 인스턴스를 만들지 않고도 호출할 수 있다는 특징이 있습니다.
스태틱 메서드를 정의하려면 다음과 같이 @staticmethod
데코레이터를 사용합니다.
class MyClass:
@staticmethod
def static_method(a:int, b:int) -> int:
return a + b
myclass1 = MyClass()
print(myclass1.static_method(3, 5)) # 8
# 인스턴스 생성 없이 바로 호출
print(MyClass().static_method(3, 5)) # 8
💡 스태틱 메서드는 인스턴스 메서드에 접근할 수 없습니다.
객체의 문자열 표현을 반환할 때, __repr__
을 이용하여 사용합니다. 이는 객체를 출력하거나 디버깅하는 데 사용됩니다.
다음과 같이 객체의 문자열을 표현할 수 있습니다.
class MyClass:
def __init__(self):
self.name = 'john'
self.age = 20
def __repr__(self) -> str:
return f'MyClass(name={self.name}, age={self.age})'
myclass1 = MyClass()
print(myclass1) # MyClass(name=john, age=20)
상속(Inheritance)은 기존 클래스에서 공통된 속성과 메서드
를 포함하는 새로운 클래스를 만드는 방법입니다. 새로운 클래스는 기존 클래스의 속성과 메서드를 그대로 사용할 수 있게 됩니다.
이렇게 상속을 받은 클래스는 자식 클래스
라 하고, 기존 클래스를 부모 클래스
라고 합니다.
다음과 같이 괄호 안에 부모 클래스 명을 입력하여 상속을 받을 수 있습니다. 10번째 줄의 super().__init__
은 부모 클래스의 생성자를 통해 Student의 name과 age를 설정하게 됩니다.
class Person: # ParentClass
def __init__(self, name: str, age: int):
self.name = name
self.age = age
def greeting(self):
return f'my name is {self.name} and {self.age} years old'
class Student(Person): # ChildClass
def __init__(self, name: str, age: int, id: int):
super().__init__(name, age)
self.id = id
def get_student_id(self):
return f'my student id is {self.id}'
john = Student(name="john", age=20, id=1)
print(john.greeting()) # my name is john and 20 years old
print(john.get_student_id()) # my student id is 1
오버라이딩(Overriding)은 부모 클래스의 메서드를 자식 클래스에서 재정의
하여 사용하는 것입니다. 오버라이딩을 통해 부모 클래스의 메서드보다 자식 클래스의 메서드가 실행됩니다.
class Person: # ParentClass
def __init__(self, name: str, age: int):
self.name = name
self.age = age
def greeting(self):
return f'my name is {self.name} and {self.age} years old'
class Student(Person): # ChildClass
def __init__(self, name: str, age: int, id: int):
super().__init__(name, age)
self.id = id
def greeting(self):
return f'my name is {self.name} and id is {self.id}'
john = Student(name="john", age=20, id=1)
print(john.greeting()) # my name is john and id is 1
💡 Python에서는 오버로딩(Overloading)은 존재하지 않습니다.