Class

class 클래스 이름 (상속 받을 클래스):
  • 최상위 클래스는 object이다.
  • 상속을 명시하지 않으면 default로 object를 상속
  • init: 생성자
  • str: 객체를 print 했을 때 출력 할 것
class SoccerPlayer: # 상속을 명시하지 않으면  default로 object를 상속
    # __init__ 은 생성자
    def __init__(self, name, position, back_number):
        self.name = name
        self.position = position
        self.back_number = back_number

    def change_back_number(self, new_number):
        print("선수 등번호 변경: From %d to %d" % (self.back_number, new_number))
        self.back_number = new_number

    # 해당 객체를 print 했을 때 출력 해주는 역할 (Java의 toString과 비슷)
    def __str__(self):
        return "Hello, My name is %s. I play in %s in center." % (self.name, self.position)


chaboom = SoccerPlayer("Chaboom", "CF", 11)

print("현재 선수의 등번호:", chaboom.back_number)
chaboom.change_back_number(9)
print("현재 선수의 등번호:", chaboom.back_number)
print()
print(chaboom)

1. 클래스 변수와 인스턴스 변수

  • 클래스 변수 (Static 변수로 사용)
    • 클래스 내, 메소드 밖에 선언 하는 변수
    • 해당 클래스로 생성한 모든 객체가 공통으로 접근할 수 있는 변수
    • 클래스명.변수명 으로 사용
  • 인스턴스 변수
    • 클래스 내부의 메소드 안에서 “self.변수명”으로 선언한 변수
    • 각 인스턴스 별로 생성
    • 객체 생성후 “객체명.변수명”으로 접근
class Car:
    # 클래스 변수
    instance_count = 0

    def __init__(self, size, color):
        # self.size, self.color는 인스턴스 변수
        self.size = size
        self.color = color
        Car.instance_count += 1
        print(f"자동차 객체의 수: {Car.instance_count}")

    def move(self):
        print(f"자동차({self.size} & {self.color})가 움직입니다.")


car1 = Car("small", 'white')
car2 = Car("big", "black")
# Car.instance_count는 car1과 car2가 공용으로 사용
print(f"Car 클래스의 총 인스턴스 수: {Car.instance_count}")
car1.move()
car2.move()
# 결과
자동차 객체의 수: 1
자동차 객체의 수: 2
Car 클래스의 총 인스턴스 수: 2
자동차(small & white)가 움직입니다.
자동차(big & black)가 움직입니다.

2. Static 메서드

  • 독립적으로 동작, 정의할 때 self를 사용하지 않음
  • static 메소드 안에서 인스턴스 메서드, 인스턴스 변수에 접근할 수 없음
  • 함수 앞에 @staticmethod를 선언하여 static 메서드를 표시
class Car:
    # 클래스 변수
    instance_count = 0

    def __init__(self, size, color):
        # self.size, self.color는 인스턴스 변수
        self.size = size
        self.color = color
        self.speed = 0
        Car.instance_count += 1
        print(f"자동차 객체의 수: {Car.instance_count}")

    def move(self, speed):
        self.speed = speed
        print(f"자동차({self.size} & {self.color})가 ", end='')
        print(f"시속 {self.speed}킬로미터로 전진")

    def auto_cruise(self):
        print("자율 주행 모드")
        self.move(self.speed)

    @staticmethod
    def check_type(model_code):
        if(model_code >= 20):
            print("이 자동차는 전기차입니다.")
        elif(10 <= model_code < 20):
            print("이 자동차는 가솔린차입니다.")
        else:
            print("이 자동차는 디젤차입니다.")


car = Car("small", "red")
car.move(80)
car.auto_cruise()
Car.check_type(25)
# 결과
자동차 객체의 : 1
자동차(small & red) 시속 80킬로미터로 전진
자율 주행 모드
자동차(small & red) 시속 80킬로미터로 전진
 자동차는 전기차입니다.

3. 클래스 메서드

  • 클래스 변수를 사용하기 위한 메서드
  • 함수 앞에 @classmethod를 선언하여 사용
class Car:
    # 클래스 변수
    instance_count = 0

    def __init__(self, size, color):
        # self.size, self.color는 인스턴스 변수
        self.size = size
        self.color = color
        self.speed = 0
        Car.instance_count += 1
        print(f"자동차 객체의 수: {Car.instance_count}")

    def move(self, speed):
        self.speed = speed
        print(f"자동차({self.size} & {self.color})가 ", end='')
        print(f"시속 {self.speed}킬로미터로 전진")

    def auto_cruise(self):
        print("자율 주행 모드")
        self.move(self.speed)

    @staticmethod
    def check_type(model_code):
        if(model_code >= 20):
            print("이 자동차는 전기차입니다.")
        elif(10 <= model_code < 20):
            print("이 자동차는 가솔린차입니다.")
        else:
            print("이 자동차는 디젤차입니다.")

    @classmethod     
    def count_instance(cls):
        print(f"클래스 변수: {cls.instance_count}")


car = Car("small", "red")
car.move(80)
car.auto_cruise()
Car.check_type(25)
Car.count_instance()

static은 객체가 생성되기 이전 부터 사용할 수 있게 하기 위해 사용됨

상속

class Bicycle:
    def __init__(self, wheel_size, color):
        self.wheel_size = wheel_size
        self.color = color

    def move(self, speed):
        print(f"자전거 시속 {speed}킬로미터로 전진")

    def turn(self, direction):
        print(f"자전거: {direction}회전")

    def stop(self):
        print(f"자전거({self.wheel_size}, {self.color}): 정지")


class FoldingBicycle(Bicycle):
    def __init__(self, wheel_size, color, state):
        super().__init__(wheel_size, color)
        self.state = state

    def fold(self):
        self.state = 'folding'
        print(f"자전거: 접기, state = {self.state}")

    def unfold(self):
        self.state = 'unfolding'
        print(f"자전거: 펴기, state = {self.state}")

1. 오버라이드(Override)

class Person:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    def about_me(self):
        print("저의 이름은", self.name, end='')
        print(f"({self.gender})이고요, 제 나이는", str(self.age), "살입니다.")


class Employee(Person):
    def __init__(self, name, age, gender, salary, hire_date):
        super().__init__(name, age, gender)
        self.salary = salary
        self.hire_date = hire_date

    def do_work(self):
        print("열심히 일을 한다.")

    def about_me(self):
        super().about_me()
        print("제 급여는", self.salary, "원이고, 제 입사일은", self.hire_date, "입니다.")


emp = Employee('Tom', 25, '남성', 350, '2020/06/02')
emp.do_work()
emp.about_me()

2. 가시성(Visibility)

  • 기본적으로 python은 public이다
  • 변수명 앞에 __를 주면 외부에서 접근이 불가능 (private)
  • 이름 앞 뒤로 __가 있는건 내부적으로 예약되어 있는 것
class Product:
    pass


class Inventory:
    def __init__(self):
        self.__items = []

    def add_new_item(self, product):
        if type(product) == Product:
            self.__items.append(product)
            print("new item added")
        else:
            raise ValueError("Invalid Item")

    def get_number_of_items(self):
        return len(self.__items)


my_inventory = Inventory()
my_inventory.add_new_item(Product())
my_inventory.add_new_item(Product())
#my_inventory.__items # Error 발생
  • python에서 getter를 만들때는 @property 데코레이터를 선언
class Product:
    pass


class Inventory:
    def __init__(self):
        self.__items = []

    def add_new_item(self, product):
        if type(product) == Product:
            self.__items.append(product)
            print("new item added")
        else:
            raise ValueError("Invalid Item")

    def get_number_of_items(self):
        return len(self.__items)

    @property
    def items(self):
        return self.__items


my_inventory = Inventory()
items = my_inventory.items
print(items)
print()
items.append(Product)
print(items)