본문 바로가기

Programming

[Python][문법] 기초 - 6. Class 2

반응형
#!/usr/bin/env python
# coding: utf-8

# # 1. 객체지향 프로그래밍(Class) II

# ### 1.1 상속

# In[ ]:


# sportcar_example1

class SportCar(object):
    def __init__(self):
        self._speed = 0

    def get_speed(self):
        return self._speed

    def start(self):
        self._speed = 20

    def accelerate(self):
        self._speed = self._speed + 40
       
    def turbocharge(self):
        self._speed = self._speed + 70

    def stop(self):
        self._speed = 0

# main

my_sportcar = SportCar()
my_sportcar.start()
print('속도 1: ', my_sportcar.get_speed() )
my_sportcar.accelerate()
print('속도 2: ', my_sportcar.get_speed() )
my_sportcar.turbocharge()
print('속도 3: ', my_sportcar.get_speed() )
my_sportcar.stop()


# #### <참고> 밑줄 2개로 시작하는 속성이나 메소드는 상속되지 않는다.

# In[ ]:


# sportcar_example2

class Car(object):
    def __init__(self):
        self._speed = 0

    @property
    def speed(self):
        return self._speed

    def start(self):
        self._speed = 20

    def accelerate(self):
        self._speed = self._speed + 30
       
    def stop(self):
        self._speed = 0
       
class SportCar(Car):
    def __init__(self):
        self._color = 'red'

    def accelerate(self):                  # 오버라이딩(Overriding, 재정의)
        self._speed = self._speed + 40
       
    def turbocharge(self):                 # 메소드 추가
        self._speed = self._speed + 70

    @property
    def color(self):
        return self._color

# main

my_sportcar = SportCar()
print('색상: ', my_sportcar.color )
my_sportcar.start()
print('속도 1: ', my_sportcar.speed )
my_sportcar.accelerate()
print('속도 2: ', my_sportcar.speed )
my_sportcar.turbocharge()
print('속도 3: ', my_sportcar.speed )
my_sportcar.stop()


# ### 1.2 다형성(Polymorphism)

# In[ ]:


# airforce

# 인터페이스(Interface)

class AirForce(object):

    def take_off(self):
        pass
   
    def fly(self):
        pass
   
    def attack(self):
        pass
   
    def land(self):
        pass
   


# In[ ]:


# fighter

# 전투기 클래스
class Fighter(AirForce):

    def __init__(self, weapon_num):
        self._missile_num = weapon_num
   
    def take_off(self):
        print('전투기 발진')
   
    def fly(self):
        print('전투기 목표지로 출격')
   
    def attack(self):
        for i in range(self._missile_num):
            print('미사일 발사')
            self._missile_num -= 1
   
    def land(self):
        print('전투기 착륙')
   


# In[ ]:


# bomber

# 폭격기 클래스
class Bomber(AirForce):

    def __init__(self, bomb_num):
        self._bomb_num = bomb_num
   
    def take_off(self):
        print('폭격기 발진')
   
    def fly(self):
        print('폭격기 목표지로 출격')
   
    def attack(self):
        for i in range(self._bomb_num):
            print('폭탄 투하')
            self._bomb_num -= 1
   
    def land(self):
        print('폭격기 착륙')
   


# In[ ]:


# war_game

def war_game(airforce):
    airforce.take_off()
    airforce.fly()
    airforce.attack()
    airforce.land()

# main

f15 = Fighter(3)
war_game(f15)

print()

b29 = Bomber(3)
war_game(b29)


# ### 1.3 인스턴스 속성과 클래스 속성

# In[ ]:


# class_variable

class Circle(object):

    PI = 3.14    # 클래스 변수
   
    def __init__(self, radius):
        self._radius = radius
   
    @property
    def radius(self):
        return self._radius

    # 원의 면적을 구한다.
    def get_area(self):
        area = Circle.PI * (self._radius ** 2)    # 클래스명을 이용해서 클래스 변수에 접근
        return round(area, 2)

    # 원의 둘레를 구한다.
    def get_circumference(self):
        circumference = 2 * self.PI * self._radius
        return round(circumference, 2)

# main

print('원주율(클래스 변수): ', Circle.PI)    # 클래스명을 이용해서 클래스 변수에 접근

circle1 = Circle(3)
print('반지름: {}, 면적: {}'.format(circle1.radius, circle1.get_area() ))
print('반지름: {}, 둘레: {}'.format(circle1.radius, circle1.get_circumference() ))

circle2 = Circle(4)
print('반지름: {}, 면적: {}'.format(circle2.radius, circle2.get_area() ))
print('반지름: {}, 둘레: {}'.format(circle2.radius, circle2.get_circumference() ))


# ### 1.4 인스턴스 메서드, 클래스 메서드, 정적 메서드

# #### <참고> 유틸리티 클래스: 클래스 메서드, 정적 메서드들로만 이루어진 클래스

# In[ ]:


# classmethod_example

class CircleCalculator(object):

    __PI = 3.14    # 외부 접근 허용 불가
   
    # __init__(self) 메서드가 필요없음
   
    # 원의 면적을 구하는 클래스 메서드
    @classmethod
    def calculate_area(cls, radius):       # 인자로 cls를 필요로 한다.
        area = cls.__PI * (radius ** 2)    # cls를 이용해서 클래스 변수에 접근
        return round(area, 2)

    # 원의 둘레를 구하는 클래스 메서드
    @classmethod
    def calculate_circumference(cls, radius):
        circumference = 2 * cls.__PI * radius
        return round(circumference, 2)

# main

print('반지름: 3, 면적: {}'.format(CircleCalculator.calculate_area(3)))
print('반지름: 3, 둘레: {}'.format(CircleCalculator.calculate_circumference(3)))


# In[ ]:


# staticmethod_example

class CircleCalculator(object):

    # __init__(self) 메서드가 필요없음
   
    # 원의 면적을 구하는 정적 메서드
    @staticmethod
    def calculate_area(radius, pi):        # 호출시 필요한 인자만 사용 (self, cls 필요없음)
        area = pi * (radius ** 2)
        return round(area, 2)

    # 원의 둘레를 구하는 정적 메서드
    @staticmethod
    def calculate_circumference(radius, pi):
        circumference = 2 * pi * radius
        return round(circumference, 2)

# main

print('반지름: 3, 면적: {}'.format(CircleCalculator.calculate_area(3, 3.14)))
print('반지름: 3, 둘레: {}'.format(CircleCalculator.calculate_circumference(3, 3.14)))


# ### 1.5 예제: 요일 구하기(객체지향 II) - classmethod

# In[ ]:


# calculate_day_name_classmethod

class DayNameCalculator(object):

    # 클래스 속성 정의
    _year_month_days = [0,31,28,31,30,31,30,31,31,30,31,30,31]
    _day_names = ['일요일','월요일','화요일','수요일','목요일','금요일','토요일']
       
    # 년월일을 입력받는 클래스 메서드
    @classmethod
    def input_date(cls):
        year  = int(input('년도를 입력하시오: '))
        month = int(input('월을 입력하시오: '))
        day   = int(input('일을 입력하시오: '))
   
        return year, month, day

    # 윤년인지를 체크하는 클래스 메서드
    @classmethod
    def _is_leap(cls, year):
        if year % 400 == 0:                 # 400으로 나뉘는 해: 윤년
            return True
        elif year % 100 == 0:               # 100으로 나뉘는 해: 평년
            return False
        elif year % 4 == 0:                 # 4으로 나뉘는 해  : 윤년
            return True
        else:
            return False
   
    # 요일을 계산하는 클래스 메서드
    @classmethod
    def calculate(cls, year, month, day):
   
        total_days = 0
       
        for item in range(1, year):
            if cls._is_leap(item):
                total_days += 366
            else:
                total_days += 365

        for item in range(1, month):
            total_days += cls._year_month_days[item]

        if month >= 3:
            if cls._is_leap(year):
                total_days += 1

        total_days += day
       
        remainder = total_days % 7
       
        return cls._day_names[remainder]
   


# In[ ]:


# main

year, month, day = DayNameCalculator.input_date()

day_name = DayNameCalculator.calculate(year, month, day)    # 객체 생성 없이 클래스 메서드 호출

print(day_name)


# ### 1.6 예제: 요일 구하기(객체지향 II) - staticmethod

# In[ ]:


# calculate_day_name_staticmethod

class DayNameCalculator(object):

    # 클래스 속성 정의
    _year_month_days = [0,31,28,31,30,31,30,31,31,30,31,30,31]
    _day_names = ['일요일','월요일','화요일','수요일','목요일','금요일','토요일']
       
    # 년월일을 입력받는 정적 메서드
    @staticmethod
    def input_date():
        year  = int(input('년도를 입력하시오: '))
        month = int(input('월을 입력하시오: '))
        day   = int(input('일을 입력하시오: '))
   
        return year, month, day

    # 윤년인지를 체크하는 정적 메서드
    @staticmethod
    def _is_leap(year):
        if year % 400 == 0:                 # 400으로 나뉘는 해: 윤년
            return True
        elif year % 100 == 0:               # 100으로 나뉘는 해: 평년
            return False
        elif year % 4 == 0:                 # 4으로 나뉘는 해  : 윤년
            return True
        else:
            return False
   
    # 요일을 계산하는 정적 메서드
    @staticmethod
    def calculate(year, month, day):
   
        total_days = 0
       
        for item in range(1, year):
            if DayNameCalculator._is_leap(item): # 클래스 속성(메소드)사용시: 클래스명으로 접근
                total_days += 366
            else:
                total_days += 365

        for item in range(1, month):
            total_days += DayNameCalculator._year_month_days[item]

        if month >= 3:
            if DayNameCalculator._is_leap(year):
                total_days += 1

        total_days += day
       
        remainder = total_days % 7
       
        return DayNameCalculator._day_names[remainder]
   


# In[ ]:


# main

year, month, day = DayNameCalculator.input_date()

day_name = DayNameCalculator.calculate(year, month, day)    # 객체 생성 없이 정적 메서드 호출

print(day_name)


# #### <참고> 라이브러리 사용

# In[ ]:


import datetime

date = datetime.date(2014,9,1)
date.strftime('%A')


# ### 1.7 특별 메서드(매직 메서드)

# In[ ]:


# car_special_method

class Car(object):

    def __init__(self, name):
        self._name = name

    def __str__(self):
        return 'Type:  Car, Name: ' + self._name
       
my_car = Car('Sonata')
my_car_string = str(my_car)

print(my_car_string)

print(my_car)


# In[ ]:


# car_special_method2

# 숫자 '+' 연산

class Car(object):

    def __init__(self, price):
        self._price = price

    def __add__(self, val):
        return self._price + val
       
    def __sub__(self, val):
        return self._price - val
       
       
my_car = Car(1000)

print('더하기 연산: ', my_car + 200 )
print('빼기   연산: ', my_car - 200 )


# In[ ]:


# car_special_method3

# 문자열 '+' 연산

class Car(object):

    def __init__(self, name):
        self._name = name

    def __add__(self, sval):
        return self._name + sval
       
my_car = Car('Sonata')

print('더하기 연산: ', my_car + ' Add string' )


# In[ ]:


dir(my_car)


# #### 연산 관련 메서드
# <center>코드|<center>파이썬 호출|<center>설 명
# :---|:---|:---
# x + y  | x.\_\_add__(y)      |덧셈을 수행한다.
# x - y  | x.\_\_sub__(y)      |뺄셈을 수행한다.
# x * y  | x.\_\_mul__(y)      |곱셈을 수행한다.
# x / y  | x.\_\_truediv__(y)  |나눗셈을 수행한다.
# x // y | x.\_\_floordiv__(y) |나눗셈후 버림을 수행한다.
# x % y  | x.\_\_mod__(y)      |나머지 연산을 수행한다.
# x ** y | x.\_\_pow__(y)      |거듭제곱을 수행한다.

# #### 비교 관련 메서드
# <center>코드|<center>파이썬 호출|<center>설명
# :---|:---|:---
# x == y | x.\_\_eq__(y)   |동등성을 평가한다.
# x != y | x.\_\_ne__(y)   |동등하지 않음을 평가한다.
# x < y  | x.\_\_lt__(y)   |보다 작음을 평가한다.
# x <= y | x.\_\_le__(y)   |같거나 작음을 평가한다.
# x > y  | x.\_\_gt__(y)   |보다 큼을 평가한다.
# x >= y | x.\_\_ge__(y)   |같거나 큼을 평가한다.
# if x:  | x.\_\_bool__(y) |x의 불린 값을 구한다.

# ---

# In[ ]:


# end of file


# In[ ]:





반응형
LIST