추가: by 변, 강, , 권, 나도

0. 클래스 핵심 용어정리

예시를 통해 이해해보자.

  • 클래스(class) : 추상화된 어떤 타입, 개념

    • 클래스는 객체를 쉽고 편리하게 생성하기 위해 만들어진 구문이다.
    • 붕어빵을 만드는 붕어빵 틀
    • ex>인간👤, 리스트(List)

  • 객체(object, 오브젝트) : 클래스를 기반으로 만들어진 특정 대상

    • 동의어: 인스턴스 (instance, 클래스를 기반으로 생성한 객체, 클래스의 객체)
    • 클래스가 구체화된 형태로 실제로 존재함
    • 객체는 속성기능으로 구성된다.
    • 실체화된 붕어빵
    • ex> 홍길동👦, 임꺽정🧔, 김희선👩 등..
      [1, 2, 3], ['hello', 'python'] 등

  • 속성(attribute | 멤버변수) : 객체를 나타내는(or 표현되는) 특징

    • ex> 남자, 160cm, 54kg, 한국사람, 검은머리, 황인종...
    • 이와 같은 키, 몸무게, 얼굴 둘레, 눈썹의 길이, 눈의 크기, 코의 크기, 입의 크기, 입술의 주름 개수, 주름 길이, 머리카락 갯수, 융털의 갯수 등등 엄청 많음
    • 변수(매개변수)를 통해 생성
    • 생성자에서 해당 클래스가 다루는 데이터를 매개변수에 정의하는데 이 정의하는 데이터가 속성임, 멤버 변수(member variable) 라고도함

  • 메서드(method, 기능, 행동, 동작 | 메소드, 메쏘드 | 함수, 클래스 함수, 멤버함수, 인스턴스 함수) : 클래스가 가지는 함수, 클래스(또는 클래스의 객체)가 행하는 행동

    • ex> 자전거타다🚴‍,수영하다♀️🏊‍ ,달리다🏃‍♂️ 등 인간이 취할 수 있는 행동,
      리스트에 요소 삭제, 추가, 변경 등...
    • 함수를 사용하여 만듬
  • 생성자(constructor) : 생성자는 객체 지향 프로그래밍에서 객체의 초기화를 담당하는 서브루틴을 가리킨다. 생성자는 객체가 처음 생성될 때 호출되어 멤버 변수를 초기화하고, 필요에 따라 자원을 할당하기도 한다. 객체의 생성 시에 호출되기 때문에 생성자라는 이름이 붙었다.

  • 생성자 함수(__init__) :클래스 이름과 같은 함수, 클래스 내부에 __init__이라는 함수(def)를 만들어 사용

  • 추상화(abstraction) :프로그램에서 필요한 요소만 사용해서 객체를 표현하는 것

    • 복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능, 속성을 간추려 내는 것
    • 위의 속성과 메서드에서 보듯이 객체의 속성과 메서드는 무한한데 이 중 프로그램상에 필요한 것만 구현하는 것을 말함

링크:클래스

1. 객체 지향 프로그래밍

객체란?

  • 클래스로 생성되어 구체화된 객체(인스턴스)
  • 파이썬의 모든 것(int, str, list..etc)은 객체(인스턴스)
  • 실제로 class가 인스턴스화 되어 메모리에 상주하는 상태를 의미
  • class가 빵틀이라면, object는 실제로 빵틀로 찍어낸 빵이라고 비유 가능

객체 지향 프로그래밍

객체를 이용한 프로그램으로, 객체속성기능으로 구성된다.

절차 지향 vs 객체 지향 프로그래밍 by 권

1. 객체 만들기

  • 객체를 생성하기 위해선 객체의 모체가 되는 class를 미리 선언해야 함

2. 객체 사용의 장점

2. 클래스와 객체 생성

클래스란?

  • 실세계의 것을 모델링하여 속성(attribute)와 동작(method)를 갖는 데이터 타입
  • python에서의 string, int, list, dict.. 모두가 다 클래스로 존재
  • 예를들어 학생이라는 클래스를 만든다면, 학생을 나타내는 속성과 학생이 행하는 행동을 함께 정의 할 수 있음
  • 따라서, 다루고자 하는 데이터(변수) 와 데이터를 다루는 연산(함수)를 하나로 캡슐화(encapsulation)하여 클래스로 표현
  • 모델링에서 중요시 하는 속성에 따라 클래스의 속성과 행동이 각각 달라짐

메서드란?

  • 클래스가 가지는 함수, 클래스의 함수
  • 클래스(또는 클래스의 객체)가 행하는 행동

    메서드를 만드는 법 (생성자를 선언하는 방법과 동일하다)
    class 클래스 이름:
      def 메서드 이름(self, 추가적인 매개변수):
        pass

  • 멤버함수, 인스턴스 함수라고도 하며, 해당 클래스의 object에서만 호출가능
  • 메쏘드는 객체 레벨에서 호출되며, 해당 객체의 속성에 대한 연산을 행함
  • {obj}.{method}() 형태로 호출됨

self란?

  • self는 현재 해당 메쏘드가 호출되는 객체 자신을 가리킴
    (자기자신을 나타내는 딕셔너리, 식별자)
  • 파이썬의 method는 항상 첫번째 인자로 self를 전달
  • 역시, 이름이 self일 필요는 없으나, 위치는 항상 맨 처음의 parameter이며 관례적으로 self로 사용
  • self가 가지고 있는 속성과 기능에 접근할 때는 self.<식별자> 형태로 접근
  • C++/C#, Java의 this에 해당

method type

  • instance method : 객체로 호출
    • 메쏘드는 객체 레벨로 호출 되기 때문에, 해당 메쏘드를 호출한 객체에만 영향을 미침
  • class method : class로 호출
    • 클래스 메쏘드의 경우, 클래스 레벨로 호출되기 때문에, 클래스 멤버 변수만 변경 가능

1. 클래스 만들기

2. 객체 만들기

class Car:

    def __init__(self, color, length):
        self.color = color
        self.length = length

    def doStop(self):
        print('STOP!!')

    def doStart(self):
        print('START!!')

    def printCarInfo(self):
        print(f'color: {self.color}')
        print(f'length: {self.length}')


car1 = Car('red', 200)
car2 = Car('blue', 300)

car1.printCarInfo()
car2.printCarInfo()

실습

class AirPlane:

    def __init__(self, color, length, weight):
        self.color = color
        self.length = length
        self.weight = weight

    def takeOff(self):
        print('take-off')

    def landing(self):
        print('landing')

    def printAriPlaneInfo(self):
        print(f'color: {self.color}')
        print(f'length: {self.length}')
        print(f'weight: {self.weight}')

airPlane1 = AirPlane('red', 200, 2000)
airPlane2 = AirPlane('blue', 150, 2200)
airPlane3 = AirPlane('green', 180, 2100)
airPlane4 = AirPlane('white', 220, 1900)
airPlane5 = AirPlane('black', 210, 2300)

airPlane1.printAriPlaneInfo()
airPlane2.printAriPlaneInfo()
airPlane3.printAriPlaneInfo()
airPlane4.printAriPlaneInfo()
airPlane5.printAriPlaneInfo()

3. 객체 속성 변경

class NewGenerationPC:
    def __init__(self, name, cpu, memory, ssd):
        self.name = name
        self.cpu = cpu
        self.memory = memory
        self.ssd = ssd

    def doExcel(self):
        print('EXCEL RUN!!')

    def doPhotoshop(self):
        print('PHOTOSHOP RUN!!')

    def printPCInfo(self):
        print(f'name: {self.name}')
        print(f'cpu: {self.cpu}')
        print(f'memory: {self.memory}')
        print(f'ssd: {self.ssd}')

myPc = NewGenerationPC('myPC', 'i5', '16G', '256G')
friendPc = NewGenerationPC('friendPC', 'i7', '32G', '512G')

myPc.printPCInfo()
friendPc.printPCInfo()

myPc.cpu = 'i9'
myPc.memory = '64G'
myPc.ssd = '1T'

myPc.printPCInfo()
friendPc.printPCInfo()

실습

 계산기 클래스를 만들고 사칙연산을 실행해 보자.


class Calculator:

    def __init__(self):
        self.number1 = 0
        self.number2 = 0
        self.result = 0

    def add(self):
        self.result = self.number1 + self.number2
        return self.result

    def sub(self):
        self.result = self.number1 - self.number2
        return self.result

    def mul(self):
        self.result = self.number1 * self.number2
        return self.result

    def div(self):
        self.result = self.number1 / self.number2
        return self.result


calculator = Calculator()
calculator.number1 = 10
calculator.number2 = 20

print(f'calculator.add(): {calculator.add()}')
print(f'calculator.sub(): {calculator.sub()}')
print(f'calculator.mul(): {calculator.mul()}')
print(f'calculator.div(): {calculator.div()}')



calculator.number1 = 3
calculator.number2 = 5

print(f'calculator.add(): {calculator.add()}')
print(f'calculator.sub(): {calculator.sub()}')
print(f'calculator.mul(): {calculator.mul()}')
print(f'calculator.div(): {calculator.div()}')

3. 생성자

객체 생성에 대해서 좀 더 자세히 살펴보자!

생성자(constructor)란?

  • 클래스 이름과 같은 함수
  • 클래스 내부에 __init__이라는 함수(def)를 만들어 사용
  • def __init__(self) 형태로 사용  

    생성자를 선언하는 법
    class 클래스 이름:
      def __init__(self, 추가적인 매개변수):
        pass

  • 첫번째 매개변수로 self가 온다는 것을 잊지 말자.
  • 생성자는 클래스 인스턴스가 생성될 때 호출됨
  • self인자는 항상 첫번째에 오며 자기 자신을 가리킴
  • 이름이 꼭 self일 필요는 없지만, 관례적으로 self로 사용
  • 생성자에서는 해당 클래스가 다루는 데이터를 정의
    • 이 데이터를 멤버 변수(member variable) 또는 속성(attribute)라고 함

class Calculator:

    def __init__(self):
        print('[Calculator] __init__() called!!')

cal = Calculator()

__init__()

class Calculator:

    def __init__(self, n1, n2):
        print('[Calculator] __init__() called!!')
        self.num1 = n1
        self.num2 = n2

cal = Calculator(10, 20)
print(f'cal.num1: {cal.num1}')
print(f'cal.num2: {cal.num2}')

4. 객체와 메모리

메모리와 객체에 대한 이해

실습

5. 인스턴스 메서드와 클래스 메서드

by 변 ch06_05

5. 얕은 복사와 깊은 복사

객체 복사에 대한 이해

얕은 복사

깊은 복사

실습

6. 클래스 상속 Class Inheritance

다른 클래스의 기능을 내 것처럼 사용하자!

상속이란?

  • 기존에 정의해둔 클래스의 기능을 그대로 물려받을 수 있다.
  • 기존 클래스에 기능 일부를 추가하거나, 변경하여 새로운 클래스를 정의한다.
  • 중복된 속성과 메소드를 쉽게 포함시킬 수 있게 해주는 기능을 한다.
  • 즉, 코드를 재사용할 수 있게된다.
  • 상속 받고자 하는 대상인 기존 클래스는 (Parent, Super, Base class 라고 부른다.)
  • 상속 받는 새로운 클래스는(Child, Sub, Derived class 라고 부른다.)
  • 의미적으로 is-a관계를 갖는다

super()

  • 하위클래스(자식 클래스)에서 부모클래스의 method를 호출할 때 사용
  • 뒤에 나오는 상속에서 상위 클래스(부모 클래스)의 메서드를 호출할 때 super().{메서드} 의 형태로 코드를 작성한다.
  • super().__init__()도 동일한 원리로 작동하며 상위 클래스를 상속받는 하위 클래스를 생성할 때 super().__init__()을 통해 상위 클래스의 생성자를 상속받는다.
  • 이처럼 중복된 속성과 메소드를 쉽게 포함시킬 수 있게 해주는 기능이 클래스의 상속입니다.

class P_Class:

    def __init__(self, pNum1, pNum2):
        print('[pClass] __init__()')

        self.pNum1 = pNum1
        self.pNum2 = pNum2


class C_Class(P_Class):

    def __init__(self, cNum1, cNum2):
        print('[cClass] __init__()')

        # P_Class.__init__(self, 100, 200)
        super().__init__(100, 200)

        self.cNum1 = cNum1
        self.cNum2 = cNum2


cls = C_Class(10, 20)

print(f'cls.cNum1: {cls.cNum1}')
print(f'cls.cNum2: {cls.cNum2}')

print(f'cls.pNum1: {cls.pNum1}')
print(f'cls.pNum2: {cls.pNum2}')

실습

class MidExam:

    def __init__(self, s1, s2, s3):
        print('[MidExam] __init__()')

        self.mid_kor_score = s1
        self.mid_eng_score = s2
        self.mid_mat_score = s3

    def printScores(self):
        print(f'mid_kor_score: {self.mid_kor_score}')
        print(f'mid_eng_score: {self.mid_eng_score}')
        print(f'mid_mat_score: {self.mid_mat_score}')

class EndExam(MidExam):

    def __init__(self, s1, s2, s3, s4, s5, s6):
        print('[EndExam] __init__()')

        super().__init__(s1, s2, s3)

        self.end_kor_score = s4
        self.end_eng_score = s5
        self.end_mat_score = s6

    def printScores(self):
        super().printScores()
        print(f'end_kor_score: {self.end_kor_score}')
        print(f'end_eng_score: {self.end_eng_score}')
        print(f'end_mat_score: {self.end_mat_score}')

    def getTotalScore(self):
        total = self.mid_kor_score + self.mid_eng_score + self.mid_mat_score
        total += (self.end_kor_score + self.end_eng_score + self.end_mat_score)

        return total

    def getAverageScore(self):
        return self.getTotalScore() / 6

exam = EndExam(85, 90, 88, 75, 85, 95)
exam.printScores()
print(f'Total: {exam.getTotalScore()}')
print(f'Average: {round(exam.getAverageScore(), 2)}')

6. 다중 상속

2개 이상의 클래스를 상속한다.

class Car01:

    def drive(self):
        print('drive() method called!!')


class Car02:

    def turbo(self):
        print('turbo() method called!!')

class Car03:

    def fly(self):
        print('fly() method called!!')


class Car(Car01, Car02, Car03):

    def __int__(self):
        pass

myCar = Car()

myCar.drive()
myCar.turbo()
myCar.fly()

실습



class BasicCalculator:

    def add(self, n1, n2):
        return n1 + n2

    def sub(self, n1, n2):
        return n1 - n2

    def mul(self, n1, n2):
        return n1 * n2

    def div(self, n1, n2):
        return n1 / n2

class DeveloperCalculator:

    def mod(self, n1, n2):
        return n1 % n2

    def flo(self, n1, n2):
        return n1 // n2

    def exp(self, n1, n2):
        return n1 ** n2


class Calculator(BasicCalculator, DeveloperCalculator):

    def __int__(self):
        pass

myCal = Calculator()
print(f'myCal.add(10, 20): {myCal.add(10, 20)}')
print(f'myCal.sub(10, 20): {myCal.sub(10, 20)}')
print(f'myCal.mul(10, 20): {myCal.mul(10, 20)}')
print(f'myCal.div(10, 20): {myCal.div(10, 20)}')

print(f'myCal.mod(10, 3): {myCal.mod(10, 3)}')
print(f'myCal.flo(10, 3): {myCal.flo(10, 3)}')
print(f'myCal.exp(10, 3): {myCal.exp(10, 3)}')

7. 오버라이딩

메서드를 재정의 한다!

method override

  • 부모 클래스의 method를 재정의(override)
  • 하위 클래스(자식 클래스) 의 인스턴스로 호출시, 재정의된 메소드가 호출됨

class Robot:

    def __init__(self, c, h ,w):
        self.color = c
        self.height = h
        self.weight = w

    def fire(self):
        print('총알 발사!!')

    def printRobotInfo(self):
        print(f'color: {self.color}')
        print(f'height: {self.height}')
        print(f'weight: {self.weight}')


class NewRobot(Robot):

    def __init__(self, c, h ,w):
        super().__init__(c, h, w)

    def fire(self):
        super().fire()
        print('레이저 발사!!')

myRobot = NewRobot('blue', 200, 300)
myRobot.printRobotInfo()
myRobot.fire()

실습

 삼각형 넓이를 계산하는 클래스를 만들고 이를 상속하는 클래스에서 getArea()를 오버라이딩 해서 출력 결과가 다음과 같을 수 있도록 클래스를 만들어보자.


class TriangleArea:

    def __init__(self, w, h):
        self.width = w
        self.height = h

    def printTriangleAreaInfo(self):
        print(f'width: {self.width}')
        print(f'height: {self.height}')

    def getArea(self):
        return self.width * self.height / 2

class NewTriangleArea(TriangleArea):

    def __init__(self, w, h):
        super().__init__(w, h)

    def getArea(self):
        return str(super().getArea()) + '㎠'

ta = NewTriangleArea(7, 5)
ta.printTriangleAreaInfo()
triangleArea = ta.getArea()
print(f'TriangleArea: {triangleArea}')

8. 추상클래스

메서드 구현을 강요한다.

from abc import ABCMeta
from abc import abstractmethod

class AirPlane(metaclass=ABCMeta):

    @abstractmethod
    def flight(self):
        pass

    def forward(self):
        print('전진!!')

    def backward(self):
        print('후진!!')


class Airliner(AirPlane):

    def __init__(self, c):
        self.color = c

    def flight(self):
        print('시속 400km/h 비행!!')


class fighterPlane(AirPlane):

    def __init__(self, c):
        self.color = c

    def flight(self):
        print('시속 700km/h 비행!!')


ap1 = Airliner('red')
ap1.flight()
ap1.forward()
ap1.backward()


ap2 = fighterPlane('blue')
ap2.flight()
ap2.forward()
ap2.backward()

실습

 계산기 추상 클래스를 만들고 이를 이용해서 새로운 계산기 클래스를 만들어 보자. 추상 클래스에는 덧셈, 뺄셈, 곱셈, 나눗셈 기능이 선언되어 있어야 한다.


class Calculator(metaclass=ABCMeta):

    @abstractmethod
    def add(self, n1, n2):
        pass

    @abstractmethod
    def sub(self, n1, n2):
        pass

    @abstractmethod
    def mul(self, n1, n2):
        pass

    @abstractmethod
    def div(self, n1, n2):
        pass


class ChildCalculator(Calculator):

    def add(self, n1, n2):
        print(n1 + n2)

    def sub(self, n1, n2):
        print(n1 - n2)

    def mul(self, n1, n2):
        print(n1 * n2)

    def div(self, n1, n2):
        print(n1 / n2)

childCal = ChildCalculator()
childCal.add(10, 20)
childCal.sub(10, 20)
childCal.mul(10, 20)
childCal.div(10, 20)


class DeveloperCalculator(Calculator):

    def add(self, n1, n2):
        print(n1 + n2)

    def sub(self, n1, n2):
        print(n1 - n2)

    def mul(self, n1, n2):
        print(n1 * n2)

    def div(self, n1, n2):
        print(n1 / n2)

    def mod(self, n1, n2):
        print(n1 % n2)

    def flo(self, n1, n2):
        print(n1 // n2)


devCal = DeveloperCalculator()
devCal.add(10, 20)
devCal.sub(10, 20)
devCal.mul(10, 20)
devCal.div(10, 20)
devCal.mod(10, 20)
devCal.flo(10, 20)

기타 _1. by 윤

1. ㅇ

# 클래스를 선언합니다.
class Student:
    # 클래스 변수
    count = 0
    students = []

    # 클래스 함수
    @classmethod
    def print(cls):
        print("------ 학생 목록 ------")
        print("이름\t총점\t평균")
        for student in cls.students:
            print(str(student))
        print("------- ------- -------")

    # 인스턴스 함수
    def __init__(self, name, korean, math, english, science):
        self.name = name
        self.korean = korean
        self.math = math
        self.english = english
        self.science = science
        Student.count += 1
        Student.students.append(self)

    def get_sum(self):
        return self.korean + self.math +\
            self.english + self.science

    def get_average(self):
        return self.get_sum() / 4

    def __str__(self):
        return "{}\t{}\t{}".format(\
            self.name,\
            self.get_sum(),\
            self.get_average())

# 학생 리스트를 선언합니다.
Student("윤인성", 87, 98, 88, 95)
Student("연하진", 92, 98, 96, 98)
Student("구지연", 76, 96, 94, 90)
Student("나선주", 98, 92, 96, 92)
Student("윤아린", 95, 98, 98, 98)
Student("윤명월", 64, 88, 92, 92)
Student("김미화", 82, 86, 98, 88)
Student("김연화", 88, 74, 78, 92)
Student("박아현", 97, 92, 88, 95)
Student("서준서", 45, 52, 72, 78)

# 현재 생성된 학생을 모두 출력합니다.
Student.print()

0개의 댓글