Red Hyundai 자동차가 생성되었습니다.
Blue Toyota 자동차가 생성되었습니다.
# 객체 삭제del car1 del car2
Red Hyundai 자동차가 삭제되었습니다.
Blue Toyota 자동차가 삭제되었습니다.
클래스 변수와 인스턴스 변수
클래스와 인스턴스 변수
구분
클래스 변수(Class Variable)
인스턴스 변수(Instance Variable)
정의 위치
클래스 내부에서 self 없이 선언
__init__() 내부에서 self.변수명 형태로 선언
공유 여부
모든 인스턴스가 공유
각 인스턴스마다 독립적
접근 방법
클래스명.변수명 또는 self.변수명
self.변수명
변경 시 영향
모든 인스턴스에 적용
해당 인스턴스에만 적용
클래스 변수는 공통 속성을 저장하는 데 사용하고, 인스턴스 변수는 개별 속성을 저장하는 데 사용하면 된다.
클래스 변수와 인스턴스 변수
클래스 변수와 인스턴스 변수 비교
구분
클래스 변수
인스턴스 변수
정의 위치
클래스 내부, self 없이 선언
클래스 내부, self를 사용하여 선언
공유 여부
모든 인스턴스가 공유
각 인스턴스마다 개별적으로 존재
접근 방법
클래스명.변수명 또는 self.변수명
self.변수명
클래스 변수
클래스 변수(Class Variable)는 모든 인스턴스가 공유하는 변수로 클래스 내부에서 self 없이 선언하며, 클래스명.변수명으로 접근할 수 있다.
클래스 변수 예제
class Car: wheels =4# 클래스 변수 (모든 자동차가 공유)def__init__(self, brand, color):self.brand = brand # 인스턴스 변수self.color = color# 객체 생성car1 = Car("Hyundai", "Red")car2 = Car("Toyota", "Blue")# 클래스 변수 접근print(Car.wheels) # 4 출력 (클래스 변수 직접 접근)print(car1.wheels) # 4 출력 (인스턴스를 통해 접근)print(car2.wheels) # 4 출력
4
4
4
# 클래스 변수 변경Car.wheels =6print(car1.wheels) # 6 출력print(car2.wheels) # 6 출력
6
6
인스턴스 변수
인스턴스 변수(Instance Variable)는 각 객체(인스턴스)마다 독립적으로 존재하는 변수, self.변수명 형태로 선언하고 사용한다.
인스턴스 변수 예제
class Car:def__init__(self, brand, color):self.brand = brand # 인스턴스 변수self.color = color# 객체 생성car1 = Car("Hyundai", "Red")car2 = Car("Toyota", "Blue")# 인스턴스 변수 접근print(car1.brand) # Hyundai 출력print(car2.brand) # Toyota 출력
Hyundai
Toyota
# 개별 인스턴스 변수 변경car1.color ="Black"print(car1.color) # Black 출력print(car2.color) # Blue 출력 (car1과 독립적)
Black
Blue
클래스 변수와 인스턴스 변수의 차이
class Animal: species ="Mammal"# 클래스 변수 (모든 인스턴스가 공유)def__init__(self, name):self.name = name # 인스턴스 변수 (각 인스턴스마다 다름)# 객체 생성dog = Animal("Dog")cat = Animal("Cat")
# 클래스 변수 접근print(dog.species) # Mammal 출력print(cat.species) # Mammal 출력
Mammal
Mammal
# 인스턴스 변수 접근print(dog.name) # Dog 출력print(cat.name) # Cat 출력
Dog
Cat
# 클래스 변수 변경 (모든 인스턴스에 영향)Animal.species ="Reptile"print(dog.species) # Reptile 출력print(cat.species) # Reptile 출력
Reptile
Reptile
# 인스턴스 변수 변경 (다른 인스턴스에 영향 없음)dog.name ="Wolf"print(dog.name) # Wolf 출력print(cat.name) # Cat 출력 (영향 없음)
Wolf
Cat
클래스 메서드
파이썬 클래스에는 인스턴스 메서드(Instance Method), 클래스 메서드(Class Method), 정적 메서드(Static Method)의 세 가지 종류가 있다.
메서드 종류
메서드 종류
정의 방식
첫 번째 매개변수
주요 특징
인스턴스 메서드
def method(self):
self
인스턴스 속성 및 메서드에 접근 가능
클래스 메서드
@classmethod 사용
cls
클래스 변수 및 메서드에 접근 가능
정적 메서드
@staticmethod 사용
없음
클래스, 인스턴스와 무관하게 독립적으로 실행
메서드와 변수
메서드 종류
self 사용 여부
cls 사용 여부
접근 가능한 변수
인스턴스 메서드
O
X
인스턴스 변수, 클래스 변수
클래스 메서드
X
O
클래스 변수
정적 메서드
X
X
클래스 및 인스턴스와 무관
각 메서드의 역할에 따라 적절히 활용하면 객체지향 프로그래밍(OOP)을 더욱 효율적으로 설계할 수 있다.
인스턴스 메서드
self 매개변수를 사용하여 인스턴스 변수 및 다른 인스턴스 메서드에 접근할 수 있다. 일반적인 메서드이며, 대부분의 메서드는 인스턴스 메서드로 작성된다.
@classmethod 데코레이터를 사용하며, 첫 번째 매개변수로 cls를 받는다. 클래스 변수에 접근 가능하며, 클래스 레벨에서 동작하는 메서드이다.
예제
class Car: wheels =4# 클래스 변수@classmethoddef set_wheels(cls, num): cls.wheels = num # 클래스 변수 변경print(f"모든 자동차의 바퀴 수가 {cls.wheels}로 변경되었습니다.")# 클래스 메서드 호출Car.set_wheels(6) # 모든 자동차의 바퀴 수가 6로 변경되었습니다.
모든 자동차의 바퀴 수가 6로 변경되었습니다.
클래스 변수 wheels를 수정할 수 있으며, 모든 인스턴스에 영향을 줌
정적 메서드
@staticmethod 데코레이터를 사용하며, 클래스나 인스턴스와 관계없이 독립적으로 동작한다. self나 cls를 사용하지 않으며, 일반적으로 단순한 유틸리티 기능을 제공할 때 사용한다.
예제
class Car:@staticmethoddef general_info():print("자동차는 도로에서 운행되는 일반적인 교통수단입니다.")# 정적 메서드 호출Car.general_info() # 자동차는 도로에서 운행되는 일반적인 교통수단입니다.
자동차는 도로에서 운행되는 일반적인 교통수단입니다.
인스턴스나 클래스 변수를 사용하지 않으므로 독립적인 기능을 수행함
메서드 비교 예제
class Example: class_var ="클래스 변수"def__init__(self, value):self.instance_var = value # 인스턴스 변수def instance_method(self): # 인스턴스 메서드print(f"인스턴스 변수: {self.instance_var}")@classmethoddef class_method(cls): # 클래스 메서드print(f"클래스 변수: {cls.class_var}")@staticmethoddef static_method(): # 정적 메서드print("정적 메서드 실행")# 객체 생성obj = Example("Hello")# 메서드 호출obj.instance_method() # 인스턴스 변수: HelloExample.class_method() # 클래스 변수: 클래스 변수Example.static_method() # 정적 메서드 실행
인스턴스 변수: Hello
클래스 변수: 클래스 변수
정적 메서드 실행
접근 제어자와 캡슐화
접근 제어자(Access Modifier)는 접근 수준에 따라 Public, Protected, Private으로 나뉜다.
접근 제어자
접근 수준
사용 방법
외부 접근 가능 여부
활용
Public
변수명
O
일반적인 속성 및 메서드
Protected
_변수명
O (권장 X)
내부적 용도 또는 상속 클래스에서 사용
Private
__변수명
X
데이터 보호 및 보안 강화
캡슐화(Encapsulation)를 통해 중요한 데이터를 보호하고, getter와 setter를 활용하면 보다 안전한 객체지향 프로그래밍이 가능하다.
접근 제어자
파이썬에서 클래스의 속성과 메서드는 접근 수준을 설정할 수 있으며, 접근 제어자는 다음과 같이 구분된다.
접근 제어자 접근 수준
접근 제어자
기호
접근 가능 범위
특징
공개(Public)
변수명
어디서든 접근 가능
기본적으로 모든 속성과 메서드는 public
보호(Protected)
_변수명
클래스 내부 및 상속받은 클래스에서 접근 가능
암묵적인 규칙으로, 강제적인 제한은 없음
비공개(Private)
__변수명
클래스 내부에서만 접근 가능
이름이 변경되어 _클래스명__변수명 형태로 변환됨
캡슐화
캡슐화는 객체의 속성(데이터)을 외부에서 직접 접근하지 못하도록 보호하는 개념으로 데이터를 숨기고(private), 메서드를 통해 안전하게 접근하도록 하는 방식이다.
접근 제어자 예제
class Person:def__init__(self, name, age):self.name = name # 공개(Public)self._age = age # 보호(Protected)self.__password ="1234"# 비공개(Private)def display_info(self):print(f"이름: {self.name}, 나이: {self._age}")def __get_password(self): # 비공개 메서드returnself.__password# 객체 생성p = Person("Alice", 30)
# Public 변수 접근 (가능)print(p.name) # Alice 출력
Alice
# Protected 변수 접근 (가능하지만 권장되지 않음)print(p._age) # 30 출력
30
# Private 변수 접근 (불가능)print(p.__password) # AttributeError 발생
---------------------------------------------------------------------------AttributeError Traceback (most recent call last)
Cell In[26], line 2 1# Private 변수 접근 (불가능)----> 2print(p.__password) # AttributeError 발생AttributeError: 'Person' object has no attribute '__password'
# Private 변수는 아래처럼 접근 가능 (권장되지 않음)print(p._Person__password) # 1234 출력
1234
Public 속성은 외부에서 자유롭게 접근 가능
Protected 속성은 _로 시작하며, 관례적으로 내부에서만 사용 (접근 가능하지만 직접 사용은 지양)
Private 속성은 __로 시작하며, 외부에서 직접 접근 불가능 (_클래스명__변수명으로 접근 가능)
캡슐화를 활용한 Getter / Setter
비공개 속성(private)에 접근하려면 Getter와 Setter 메서드를 사용해야 한다.
# Setter 사용account.set_balance(2000)print(account.get_balance()) # 2000 출력
2000
# 직접 접근 불가print(account.__balance) # AttributeError 발생
---------------------------------------------------------------------------AttributeError Traceback (most recent call last)
Cell In[31], line 2 1# 직접 접근 불가----> 2print(account.__balance) # AttributeError 발생AttributeError: 'BankAccount' object has no attribute '__balance'
상속 개념과 활용
상속(Inheritance)은 부모 클래스 속성과 메서드를 자식 클래스가 사용할 수 있도록 하는 방법이다.
상속 개념
개념
설명
단일 상속
하나의 부모 클래스를 상속
다중 상속
여러 개의 부모 클래스를 상속
메서드 오버라이딩
부모 클래스의 메서드를 자식 클래스에서 재정의
super()
부모 클래스의 메서드를 호출할 때 사용
상속은 코드의 재사용성과 유지보수성을 높이지만, 불필요한 상속은 코드 복잡성을 증가시킬 수 있으므로 신중하게 설계해야 한다.
상속 개념
상속은 기존 클래스(부모 클래스, superclass)의 속성과 메서드를 새로운 클래스(자식 클래스, subclass)가 물려받아 사용할 수 있도록 하는 개념으로 코드의 재사용성을 높이고, 클래스 간의 관계를 구조화할 수 있다.
상속 기본 문법
class 부모클래스:# 부모 클래스 정의class 자식클래스(부모클래스):# 부모 클래스를 상속받은 자식 클래스 정의
상속 기본 예제
# 부모 클래스 정의class Animal:def__init__(self, name):self.name = namedef speak(self):print("동물이 소리를 냅니다.")# 자식 클래스 (Animal을 상속)class Dog(Animal):def speak(self): # 메서드 오버라이딩 (재정의)print(f"{self.name}가 멍멍 짖습니다.")# 객체 생성dog = Dog("바둑이")dog.speak() # 바둑이가 멍멍 짖습니다.
바둑이가 멍멍 짖습니다.
Dog 클래스는 Animal 클래스를 상속받아 name 속성과 speak() 메서드를 그대로 사용 가능
speak() 메서드는 자식 클래스에서 재정의(오버라이딩, overriding) 가능
super()를 사용한 부모 클래스 접근
super()를 사용하면 부모 클래스의 메서드를 자식 클래스에서 호출 가능하다.
class Animal:def__init__(self, name):self.name = namedef speak(self):print("동물이 소리를 냅니다.")class Dog(Animal):def__init__(self, name, breed):super().__init__(name) # 부모 클래스의 __init__() 호출self.breed = breeddef speak(self):super().speak() # 부모 클래스의 speak() 호출print(f"{self.name}가 멍멍 짖습니다.")# 객체 생성dog = Dog("바둑이", "진돗개")dog.speak()
동물이 소리를 냅니다.
바둑이가 멍멍 짖습니다.
다중 상속
파이썬에서는 여러 개의 부모 클래스를 동시에 상속(Multiple Inheritance)받을 수 있다. 다중 상속 시 MRO(Method Resolution Order, 메서드 탐색 순서)가 적용된다.
class A:def method_a(self):print("A 클래스의 메서드")class B:def method_b(self):print("B 클래스의 메서드")class C(A, B): # A와 B를 동시에 상속def method_c(self):print("C 클래스의 메서드")# 객체 생성obj = C()obj.method_a() # A 클래스의 메서드obj.method_b() # B 클래스의 메서드obj.method_c() # C 클래스의 메서드
5000원 입금되었습니다. 현재 잔액: 15000원
이자 750.0원이 추가되었습니다. 현재 잔액: 15750.0원
3000원 출금되었습니다. 현재 잔액: 12750.0원
상속 장점과 단점
상속 장점과 단점
장점
단점
코드 재사용성이 높아짐
다중 상속 시 복잡성이 증가
유지보수성이 향상됨
부모 클래스가 변경되면 자식 클래스도 영향을 받을 수 있음
코드 중복을 줄일 수 있음
잘못된 설계 시 불필요한 상속이 발생할 수 있음
상속과 캡슐화 결합
상속을 사용할 때는 캡슐화(Private, Protected 변수)와 함께 활용하여 데이터 보호를 강화할 수 있다.
class Parent:def__init__(self):self._protected_var ="보호된 변수"# Protectedself.__private_var ="비공개 변수"# Privatedef get_private_var(self):returnself.__private_var # Getter 메서드class Child(Parent):def show_vars(self):print(self._protected_var) # 접근 가능# print(self.__private_var) # 접근 불가 (AttributeError 발생)print(self.get_private_var()) # Getter를 통해 접근 가능obj = Child()obj.show_vars()
보호된 변수
비공개 변수
다형성과 추상 클래스
다형성을 사용하면 동일한 메서드가 여러 객체에서 다르게 동작할 수 있다. 추상 클래스는 자식 클래스가 공통된 메서드를 구현하도록 강제하며, 구체적인 동작은 자식 클래스에 위임한다. 다형성과 추상 클래스를 결합하면 유연하고 확장 가능한 코드를 작성할 수 있다.
다형성 개념
다형성(Polymorphism)은 동일한 이름의 메서드나 함수가 여러 다른 방식으로 동작할 수 있게 하는 개념이다. 객체 지향 프로그래밍에서 다양한 객체들이 동일한 인터페이스(메서드)를 통해 서로 다른 동작을 수행할 수 있도록 한다. 메서드 오버라이딩(Method Overriding)과 메서드 오버로딩(Method Overloading)이 다형성의 주요 기법이다.
메서드 오버라이딩 (Method Overriding)
부모 클래스의 메서드를 자식 클래스에서 재정의하여, 자식 클래스 객체가 호출할 때 다른 동작을 할 수 있도록 한다.
메서드 오버로딩 (Method Overloading)
동일한 이름의 메서드를 다양한 매개변수로 정의하는 방식이다. 하지만, 파이썬은 메서드 오버로딩을 기본적으로 지원하지 않으므로, 보통 기본값 인수나 가변 인수를 사용하여 구현한다.
다형성 예제 (Method Overriding)
class Animal:def speak(self):print("동물이 소리를 냅니다.")class Dog(Animal):def speak(self): # 메서드 오버라이딩print("멍멍!")class Cat(Animal):def speak(self): # 메서드 오버라이딩print("야옹!")# 객체 생성animals = [Dog(), Cat()]# 다형성: 동일한 인터페이스(speak())지만 각기 다른 동작을 함for animal in animals: animal.speak()
멍멍!
야옹!
Dog와 Cat 객체가 각각 speak() 메서드를 오버라이딩하여 각기 다른 방식으로 동작함.
추상 클래스 개념
추상 클래스(Abstract Class)는 직접 인스턴스를 생성할 수 없고, 자식 클래스에서 반드시 구현해야 하는 메서드를 정의하는 클래스이다. 추상 메서드를 포함하고 있으며, 자식 클래스에서 이를 구현(Override)하도록 강제한다. 추상 클래스는 abc 모듈을 사용하여 정의할 수 있다.
추상 클래스 사용 이유
공통된 인터페이스를 강제하고, 구체적인 구현은 자식 클래스에 맡겨 구현의 일관성을 유지할 수 있다.
여러 클래스에서 공통적으로 구현해야 하는 메서드를 정의하고, 이를 자식 클래스에서 구체화하도록 한다.
추상 클래스 예제
from abc import ABC, abstractmethod# 추상 클래스 정의class Animal(ABC):@abstractmethoddef speak(self): # 추상 메서드passclass Dog(Animal):def speak(self): # 추상 메서드 구현print("멍멍!")class Cat(Animal):def speak(self): # 추상 메서드 구현print("야옹!")# 객체 생성dog = Dog()cat = Cat()# 추상 클래스의 메서드를 자식 클래스에서 구현해야 하므로 오류가 발생하지 않음dog.speak() # 멍멍!cat.speak() # 야옹!
멍멍!
야옹!
Animal 클래스는 추상 클래스로 정의되어 있고, speak() 메서드는 자식 클래스에서 반드시 구현해야 한다.
Dog와 Cat 클래스에서 speak() 메서드를 구현하여 오류 없이 동작한다.
추상 클래스와 인스턴스화
추상 클래스는 직접 인스턴스화할 수 없다.
# 직접 인스턴스를 생성할 수 없음animal = Animal() # TypeError 발생: Can't instantiate abstract class Animal with abstract methods speak
---------------------------------------------------------------------------TypeError Traceback (most recent call last)
Cell In[40], line 2 1# 직접 인스턴스를 생성할 수 없음----> 2 animal =Animal()# TypeError 발생: Can't instantiate abstract class Animal with abstract methods speakTypeError: Can't instantiate abstract class Animal with abstract method speak
추상 클래스는 인스턴스를 생성할 수 없고, 반드시 이를 상속받은 자식 클래스에서 구체적인 구현을 해야만 인스턴스를 생성하고 사용할 수 있음
다형성과 추상 클래스의 결합
다형성을 활용하여 추상 클래스를 공통된 인터페이스로 사용하고, 구체적인 구현은 자식 클래스에서 제공하도록 할 수 있다.
from abc import ABC, abstractmethodclass Shape(ABC):@abstractmethoddef area(self):passclass Circle(Shape):def__init__(self, radius):self.radius = radiusdef area(self):return3.14*self.radius *self.radiusclass Rectangle(Shape):def__init__(self, width, height):self.width = widthself.height = heightdef area(self):returnself.width *self.height# 객체 생성shapes = [Circle(5), Rectangle(4, 6)]# 다형성을 통한 추상 클래스 메서드 호출for shape in shapes:print(shape.area())
shapes 리스트에서 Circle과 Rectangle 객체들을 다루며, 다형성을 통해 동일한 인터페이스로 각기 다른 방식으로 area() 메서드를 호출
다형성, 추상 클래스, 상속 결합
다형성, 추상클래스, 상속
개념
설명
예시
다형성
같은 이름의 메서드가 객체의 종류에 따라 다르게 동작
speak() 메서드
추상 클래스
자식 클래스에 공통적인 인터페이스를 강제, 직접 인스턴스화 불가
Animal 추상 클래스
상속
부모 클래스에서 자식 클래스가 속성이나 메서드를 물려받음
Dog, Cat 클래스
연산자 오버로딩
연산자 오버로딩(Operator Overloading)은 객체 지향 프로그래밍에서 연산자를 커스터마이즈하여 클래스에 맞게 동작하게 만드는 기법이다. 이를 통해 직관적이고 유연한 객체 연산이 가능하지만, 과용하면 코드의 가독성과 유지보수성에 문제가 될 수 있다.
연산자 오버로딩 개념
연산자 오버로딩은 기존의 연산자가 클래스에 대해 새로운 의미로 동작하도록 만드는 기능이다. 기본 연산자(예: +, -, *, ==)의 동작 방식을 사용자가 정의한 클래스에 맞게 재정의할 수 있다. 이를 통해 자체적으로 정의한 객체들 간의 연산을 직관적으로 사용할 수 있게 된다.
연산자 오버로딩의 예시
파이썬에서는 연산자에 해당하는 특수 메서드(매직 메서드)를 정의함으로써 연산자 오버로딩을 구현한다. 예를 들어, + 연산자는 __add__() 메서드를 통해 오버로딩할 수 있다.
주요 연산자 오버로딩 메서드
연산자
메서드
+
__add__(self, other)
-
__sub__(self, other)
*
__mul__(self, other)
/
__truediv__(self, other)
==
__eq__(self, other)
!=
__ne__(self, other)
<
__lt__(self, other)
>
__gt__(self, other)
연산자 오버로딩 예제
+ 연산자 오버로딩 예제
class Point:def__init__(self, x, y):self.x = xself.y = ydef__add__(self, other): # + 연산자 오버로딩return Point(self.x + other.x, self.y + other.y)def__str__(self): # 출력 형식 지정returnf"({self.x}, {self.y})"# 객체 생성point1 = Point(1, 2)point2 = Point(3, 4)# + 연산자를 사용하여 두 점을 더하기result = point1 + point2print(result) # (4, 6)
(4, 6)
__add__() 메서드는 두 Point 객체의 x와 y 좌표를 더하여 새로운 Point 객체를 반환
+, *, == 연산자를 오버로딩하여 Vector 객체에 대해 벡터 덧셈, 스칼라 곱, 비교 연산 가능
연산자 오버로딩 시 주의사항
연산자 오버로딩을 너무 남용하면 코드의 가독성이 떨어질 수 있다. 연산자 오버로딩을 사용한 코드가 직관적이어야 한다. 기본 연산자들의 의미를 지나치게 변경하면 예상치 못한 동작을 할 수 있으므로, 명확한 목적을 가지고 오버로딩을 활용하는 것이 중요하다.
연산자 오버로딩 장단점
연산자 오버로딩 장점과 단점
장점
단점
객체 간의 직관적이고 간결한 연산을 가능하게 한다.
연산자 오버로딩이 지나치면 코드의 직관성이 떨어질 수 있다.
객체의 구체적인 동작을 추상화할 수 있어 코드의 가독성을 높일 수 있다.
각 연산자의 의미가 명확히 정의되지 않으면, 의도치 않은 오류가 발생할 수 있다.
클래스 활용 및 실전 예제
클래스 활용 개념
클래스는 객체 지향 프로그래밍(OOP)에서 중요한 개념으로, 데이터와 이를 처리하는 메서드를 하나의 단위로 묶을 수 있다. 이를 통해 재사용성, 확장성, 유지보수 용이성 등의 장점이 생긴다. 클래스는 특히 복잡한 시스템을 개발할 때 코드를 모듈화하고, 구체화하는 데 큰 도움이 된다.
클래스 활용 중요성
클래스 활용 중요성은 다음과 같다.
코드 재사용: 동일한 구조를 가진 여러 객체를 만들 때 클래스는 코드의 재사용을 가능하게 한다.
추상화: 현실 세계의 복잡한 객체를 단순화하여 중요한 정보만을 다룰 수 있게 한다.
캡슐화: 데이터를 하나로 묶어 내부 구현을 숨기고, 외부와의 인터페이스만을 제공한다.
상속과 다형성: 부모 클래스의 기능을 자식 클래스에 물려주어, 기존 코드를 수정하지 않고 새로운 기능을 추가할 수 있다.
# 가격 및 재고 변경product1.update_price(950000)product2.update_stock(5)
노트북의 가격이 950000로 변경되었습니다.
스마트폰의 재고가 25개로 변경되었습니다.
Product 클래스는 제품명, 가격, 재고를 속성으로 가짐
가격과 재고 변경은 update_price()와 update_stock() 메서드를 통해 수행
제품 정보 출력 메서드를 통해 제품 정보를 쉽게 확인 가능
실전 예제 3: 학생 성적 관리 시스템
목표: 학생의 성적을 관리하고, 평균 성적을 계산하는 클래스를 작성
class Student:def__init__(self, name, grades):self.name = name # 학생 이름self.grades = grades # 성적 리스트def add_grade(self, grade):"""성적 추가 메서드"""self.grades.append(grade)def average_grade(self):"""평균 성적 계산 메서드"""returnsum(self.grades) /len(self.grades) ifself.grades else0def student_info(self):"""학생 정보 및 성적 출력 메서드"""returnf"학생명: {self.name}, 성적: {self.grades}, 평균 성적: {self.average_grade():.2f}"# 학생 객체 생성student1 = Student("홍길동", [85, 90, 78])student2 = Student("김유진", [92, 88, 95])
# 학생 정보 출력print(student1.student_info())print(student2.student_info())
학생명: 홍길동, 성적: [85, 90, 78], 평균 성적: 84.33
학생명: 김유진, 성적: [92, 88, 95], 평균 성적: 91.67
# 성적 추가 및 정보 갱신student1.add_grade(80)print(student1.student_info())
학생명: 홍길동, 성적: [85, 90, 78, 80], 평균 성적: 83.25
Student 클래스는 학생의 이름과 성적 리스트를 속성으로 가짐
성적을 추가할 수 있는 add_grade() 메서드와, 평균 성적을 계산하는 average_grade() 메서드를 제공
클래스 활용 시 주의사항
클래스 활용 시 주의사항은 다음과 같다.
책임 분리: 클래스는 하나의 책임만 가지도록 설계하는 것이 좋다. 여러 가지 기능이 혼합되면 유지보수와 확장이 어려워진다.
적절한 추상화: 클래스는 필요한 정보를 추상화하여 복잡성을 줄이고, 객체들 간의 상호작용을 단순화해야 한다.
상속과 다형성 활용: 공통된 기능을 부모 클래스에 정의하고, 상속을 통해 자식 클래스에서 기능을 확장할 수 있다.