OOP와 클래스(Class)
- 프로그램이 복잡해지는 경우, 프로그램을 효율적으로 작성할 필요가 있으며, 이때 이용되는 개념들이 OOP와 Class라는 개념임
- Class는 객체 지향 프로그래밍(OOP, Object Oriented Programming)을 위해 사용되는 것으로, 데이터(속성)와 메서드(처리)를 함께 사용할 수 있는 구조로 이루어져 있음.
- 즉, 변수와 함수들을 하나의 객체(Object)로써 묶어서 관리할 수 있다는 의미!
1. OOP (객체지향 프로그래밍)
- OOP (Object Oriented Programming)란, 실체가 있는 모든 물체를 클래스와 인스턴스, 함수, 변수라는 object로 변화시켜서 프로그램을 구성하는 개발방식을 의미함
- 최소비용으로 최대효율을 얻기위해 개발되었고, 속성과 기능을 object라는 최소단위로 분리하는 프로그래밍의 패러다임을 의미함
- 하나의 패러다임일 뿐이기 때문에 기존의 프로그래밍 패러다임(Procedural Programming, Functional Programming)과의 우열을 가릴 수는 없지만, 속성과 기능이 증가할 때마다 배열과 함수를 계속 생성해야 하는 경우에 소스코드를 보다 효율적으로 관리할 수 있음
OOP 이전의 프로그래밍 패러다임과 OOP
- Procedural Programming (절차형, 순서형 프로그래밍)
- 조건, 기능, 변수를 순서대로 정의하고 실행하는 방법
- 간단한 프로그래밍에서 이용되는 일반적인 방법을 의미
- 조건 또는 기능이 증가할 때마다 함수와 변수등 정의해야할 요소들이 계속 증가하기 때문에 프로그램이 복잡해질수록 비효율적임
speed = 50
color = 'black'
model = 'CarModel'
print("Car Attribute: ", speed, color, model)
'''
Car Attribute: 50 black CarModel
'''
- Functional Programming (함수형 프로그래밍)
- 함수형은 함수의 사용을 극대화시켜서 코드의 가독성을 높여주는 형태
- 특정 상황에 특정 함수를 재사용하여 프로그래밍 효율을 높이기위해 고안된 방법
- 일반적으로 많이 쓰이고 있지만 이 역시도 프로그램이 복잡해지는 경우 비효율이 발생할 수 있어 절대적으로 좋은 프로그래밍 방식이라고는 볼 수 없음
def carAttribute():
speed = 50
color = 'black'
model = 'CarModel'
return speed,color,model
print("Car Attribute: ", carAttribute())
'''
Car Attribute: (50, 'black', 'CarModel')
'''
- Object Oriented Programming (객체지향 프로그래밍)
- 절차 프로그래밍과 다르게 기능별로 수행하며, 데이터(속성)와 메서드(처리)를 함께 사용할 수 있는 구조로 프로그래밍 하는 방법
- 주로 Class를 통해 구현되고, 클래스 선언 순서에 관계없이 실행할 수 있음
- Python의 자료형(int, float, bool, list, tuple ... 등)은 class의 형태로 구현된 것이며, 따라서 파이썬의 자료구조 및 자료형은 객체지향 프로그래밍이 적용된 것이라 볼 수 있음
- 다만, 무분별하게 활용하면 유지보수가 어려워질 수도 있기때문에 설계방향 및 서비스기능에 따라 사용하는 것이 좋으며, 기능별로 개체가 효율적으로(재사용가능하도록) 분리되어야 하기 때문에 효율적인 설계가 매우 중요함
class Car:
def __init__(self, speed, color, model):
self.speed = speed
self.color = color
self.model = model
def drive(self):
self.speed = 50
myCar = Car(0, "green", "testCar")
print("--------Car Object Create Complete--------")
print("Car Speed: ", myCar.speed)
print("Car Color: ", myCar.color)
print("Car Model: ", myCar.model)
'''
--------Car Object Create Complete--------
Car Speed: 0
Car Color: green
Car Model: testCar
'''
print("Car Speed by drive: ", myCar.speed)
'''
Car Speed by drive: 0
'''
myCar.drive()
print("Car Speed by drive: ", myCar.speed)
'''
Car Speed by drive: 50
'''
2. Class (클래스)
- Class에서는 변수, 함수 등을 함께 기술해야 하며, 이를
클래스 정의
라고 함
- Class명은 맘대로 지어도 상관은 없지만, 일반적으로 변수이름과 구분하기 위해
첫문자는 대문자
로 설정하는 것이 일종의 암묵적인 약속임 (변수의 첫문자는 클래스와 구분 짓기 위해 소문자로 설정하는 것이 국룰..!)
class 클래스명(상속받는 경우의 상위클래스):
def 메서드명(self, 인수 목록):
self.변수 = ...
...
return ...
- 클래스 정의 예시
- 여기서
self
의 의미에 대해선 인스턴스의 개념과 클래스 변수의 개념을 함께 알아야 설명이 가능해서 이에 관련해선 2-4 파트에서 다시 다룰 것이고, 일단은 변수와 메서드에 self를 붙여야 객체로써 관리할 수 있다는 정도로 이해하고 넘어가도록 하자
class Person:
def getName(self):
return self.name
def getAge(self):
return self.age
- 인스턴스(instance)를 작성
- 클래스로부터 생성되는 각각의 존재를 인스턴스(instance)라 부름
- 예를 들면, Person 클래스로부터 작성된 개개인의 사람들이 각각 인스턴스에 해당함을 의미함
- 인스턴스는
클래스명()
을 통해 정의할 수 있고, 인스턴스를 나타내는 변수(인스턴스명)에 대입하여 변수를 정의할 수 있음
- 이때 클래스의 메소드나 속성을 이용하기 위해
.
을 통해 접근할 수 있음
인스턴스명 = 클래스명()
person1 = Person()
인스턴스명.속성
person1.name
인스턴스명.메서드(인수목록)
person1.getName()
class Person:
def getName(self):
return self.name
def getAge(self):
return self.age
person_1 = Person()
person_1.name = "홍길동"
person_1.age = 24
name_1, age_1 = person_1.getName(), person_1.getAge()
print(f"{name_1}님은 {age_1}세 입니다.")
'''
홍길동님은 24세 입니다.
'''
person_2 = Person()
person_2.name = "임꺽정"
person_2.age = 33
name_2, age_2 = person_2.getName(), person_2.getAge()
print(f"{name_2}님은 {age_2}세 입니다.")
'''
임꺽정님은 33세 입니다.
'''
3. 클래스 생성자(constructor)
- 인스턴스를 작성할 때 초기 값을 주거나, 초기화처리를 하고자 하는 경우 등
인스턴스가 작성될 때 처음에 반드시 처리되도록 하는 메서드
를 생성자(constructor)
라 부름
- 생성자는
__init__
이라는 이름을 가지는 메서드로써 정의하고, 양옆의 2개의 언더바_
는 반드시 지켜줘야함
def __init__(self, 인수목록):
...
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def getName(self):
return self.name
def getAge(self):
return self.age
persons = [Person("홍길동", 24), Person("임꺽정", 33)]
for person in persons:
name = person.getName()
age = person.getAge()
print(f"{name}님은 {age}세 입니다.")
'''
홍길동님은 24세 입니다.
임꺽정님은 33세 입니다.
'''
4. 클래스 변수와 클래스 메서드
- 현재까지 살펴본 메서드와 변수들은
self
구문을 통해 정의되었고, 이는 각각의 인스턴스에 관련되어있는 변수(속성) 혹은 함수(메서드)였음
- 즉,
self
가 붙어있는 변수는 인스턴스마다 다르게 저장되는 변수이기 때문에 이러한 변수를 인스턴스 변수
라 부름
- 또한,
self
를 인수로 가지는 메서드는 인스턴스 자기자신을 의미하는 것으로써 이러한 메서드를 인스턴스 메서드
라 부름
- 하지만 각각의 인스턴스가 아닌 클래스 전체(전체 인스턴스)에서 공유하여 값을 저장하거나 처리해야하는 경우가 있을 수 있고, 이러한 경우엔 속성이나 메서드는 클래스 전체에 관련되어 따로 정의하거나 처리해주어야함
- 예를 들어 클래스를 통해 몇개의 인스턴스가 생성되었는지를 기억하고자 하는 경우에는 클래스 전체에서 값을 공유하여 저장해야 하고, 이처럼 클래스 전체에 관련된 속성과 메서드를
클래스 변수
, 클래스 메서드
라 부름
클래스 변수와 인스턴스 변수
class Person:
count = 0
def getName(self):
return self.name
- 위 예시처럼 클래스 아래에서 정의되어 클래스에 하나의 값만 존재하는 변수 혹은 속성을
클래스변수
혹은 정적변수
라 부름
self
가 붙어있는 데이터 속성은 인스턴스마다 값이 존재하기 때문에, 이러한 속성은 클래스 변수와 구분하기 위해 인스턴스 변수
라 부름
클래스 메서드와 인스턴스 메서드
- 클래스 전체에 관련된 메서드를
클래스 메서드
라 부르며, 클래스 메서드는 클래스 내부에서 정의할 메서드 위에 데코레이터(@classmethod
)를 통해 정의해 주어야 함
@classmethod
def getCount(변수명):
return 변수명.count
클래스명.getCount()
self
를 인수로서 가지는 메서드는 클래스 메서드와 구분짓기 위해 인스턴스 메서드
라 부르고, 이때 self는 인스턴스 자신(자기자신)을 의미함
def getName(self):
return self.name
name = Person('이름').getName()
- 예시를 통해 알아보는 클래스 변수, 클래스 메서드
class Person:
inst_count = 0
def __init__(self, name, age):
Person.inst_count += 1
self.name = name
self.age = age
def getName(self):
return self.name
def getAge(self):
return self.age
@classmethod
def getCount(c):
return c.inst_count
persons = [Person("홍길동", 24), Person("임꺽정", 33), Person("무야호", 40)]
for person in persons:
name = person.getName()
age = person.getAge()
print(f"{name}님은 {age}세 입니다.")
print(f"\n총 인원수는 {Person.getCount()}명 입니다.")
'''
홍길동님은 24세 입니다.
임꺽정님은 33세 입니다.
무야호님은 40세 입니다.
총 인원수는 3명 입니다.
'''
5. 클래스의 캡슐화(capsulization)
- 객체지향 프로그래밍(OOP)에서는 본래 사물의 데이터를 속성으로 인스턴스화하여 정보를 처리하는데, 이러한 객체지향에서는 데이터 속성을 마음대로 변경 할 수 없도록 처리를 해주어야하고, 이러한 처리를 통해 잘못된 값이 설정되지 않도록 처리할 수 있음
- 일반적인 객체 지향에 의한 프로그래밍 언어에서는 클래스의 외부로부터 object 속성에 접근할 수 없도록 하는 구조를 사용하여, 프로그램에서 발생 가능한 문제를 미연에 방지하게 됨
- 하지만, Python에서는 언어의 간단한 사용을 중요시하다보니 object에 대한 접근제어를 위한 접근제어자를 제공하지 않기 때문에, 객체의 변수, 메서드, 함수에 직접적으로 접근할 수 있음
- 이러한 한계를 극복하기위해 파이썬에서는 직접 접근을 허용하지 않도록 규칙을 만들어 두었는데, 접근 정도와 단계를 나타내는
Notation
이라는 개념을 통해 접근 가능한 정도를 설정할 수 있음
- 파이썬의 Notation에는 다음과 순서로 코드 접근을 어렵게 설정할 수 있음
- (접근 어려움) Private -> Protected -> Public (접근 쉬움)
Public
: 내부와 외부에서 쉽게 접근할수 있고 수정할 수도 있음
Protected
: 언더바 1개 _
를 이름 앞에 붙여 외부에서 쉽게 접근하지 못하도록 함
- 실제로는 접근이 되지만 개발자간의 암묵적인 약속으로 정한 것이라 보면 됨
Private
: 언더바 2개__
를 이름 앞에 붙여 외부에서의 접근을 수정을 강제로 금지시킴
- TMI : 사실 아무리 Private으로 설정하더라도
_클래스이름__메서드이름
혹은 _클래스이름__변수이름
형태로 접근하면 강제적으로 접근 할 수 있어서 파이썬 코드상으로 접근을 강제적으로 막을 방법이 없긴 해서, Python에서는 접근을 어렵게 하기위한 최선의 방법이라 생각하면 될 듯함
- 이처럼 데이터를 안전하게 유지하고, 외부로부터 마음대로 접근할 수 없도록 하는 것을 객체지향에서는
캡슐화(capsulization)
라고 부름
class Encap:
def __init__(self,value):
self.value = value
print('init:', self.value)
def _set(self):
print('set:', self.value)
def printTest(self):
print('printTest:', self.value)
def __printTest2(self):
print('printTest:', self.value)
e = Encap(10)
'''
init: 10
'''
e.__init__(20)
e._set()
e.printTest()
'''
init: 20
set: 20
printTest: 20
'''
e.__printTest2()
'''
AttributeError: 'Encap' object has no attribute '__printTest2'
'''
e.__init__(30)
e._set()
e.printTest()
'''
init: 30
set: 30
printTest: 30
'''
- 특히 프로그램이 길어지고 다양한 변수를 선언하는 경우 클래스의 속성이 충돌(변수의 중복)할 수 있는데, 이럴땐 속성명을 다르게 해줘도 되지만 파이썬에서 활용할 수 있는 '비공개 속성'을 활용하여 충돌을 방지할 수 있음
class parent_class:
def __init__(self):
self.value = 30
self._value = 40
self.__value = 50
def get(self):
return self.value
class sub_class(parent_class):
def __init__(self):
super().__init__()
self.__value = 20
s = sub_class()
print(s.value)
print(s._value)
'''
30
40
'''
print('----- 어떤 클래스에서 값을 받아오냐에 따라 값의 정보가 바뀜 -----')
print(s._parent_class__value)
print(s._sub_class__value)
print('parent_class value:', s.get(), ', sub_class value:', s.value)
'''
----- 어떤 클래스에서 값을 받아오냐에 따라 값의 정보가 바뀜 -----
50
20
parent_class value: 30 , sub_class value: 30
'''
6. 클래스의 상속, 포함, 오버라이딩
상속(inheritance)
- 이미 정의한 클래스를 바탕으로 새로운 클래스를 정의할 수 있는데, 이처럼 새로운 클래스를 확장하여 정의하는 것을 클래스를
확장(Extension)
한다고 표현함
- 이러한 클래스 확장은 기존 클래스의 속성과 메서드를
상속
받는 형태로 이루어지며, 이때는 기존의 클래스의 속성과 메서드를 다시 적을 필요가 없이 새로운 속성과 메서드를 추가하여 코드를 작성할 수 있음
- 이처럼 새롭게 확장한 클래스가 기존의 클래스의 속성과 메서드를 물려받는 것을
상속(inheritance)
이라 부름
- 속성과 메서드를 물려주는 기존 클래스를
기저클래스(base class)
혹은부모클래스
라 부름
- 속성과 메서드를 상속받는 새로운 클래스를
파생클래스(derived class)
혹은자식클래스
라 부름
class 파생클래스명(기저클래스명):
...
def 추가메서드명(self, 인수목록):
self.추가속성 = 값
...
class Person:
def __init__(self, name):
self.name = name
class Student(Person):
def study(self):
print (self.name + " studies hard")
class Employee(Person):
def work(self):
print (self.name + " works hard")
s = Student("Dave")
e = Employee("David")
s.study()
e.work()
'''
Dave studies hard
David works hard
'''
포함(Composition)
- 속성과 메서드를 모두 받는 상속과 달리 클래스의 일부 변수와 기능만 가져오는 경우는
포함(Composition)
이라 부르며, 이때는 기저클래스나 파생클래스로 구분을 할 수 없고, 새롭게 정의하는 클래스 내부에서 클래스를 호출함으로써 가져올 수 있음
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def printPerson(self, name, age):
print('Person_printPerson', name, age)
class Student:
def __init__(self, name, age, id):
self.person = Person(name,age)
Person.__init__(self, name, age)
self.id = id
def test(self, score):
if score > 80:
return (self.person.printPerson(self.name, self.age))
else:
print (self.name + " needs supplementary lessons")
s = Student("Dave", 20, 1)
print("s.age:", s.name)
print("s.age:", s.age)
print("s.id:", s.id)
'''
s.age: Dave
s.age: 20
s.id: 1
'''
s2 = Student("Jamie", 25, 2)
print("s2.age:", s2.name)
print("s2.age:", s2.age)
print("s2.id:", s2.id)
'''
s2.age: Jamie
s2.age: 25
s2.id: 2
'''
print('-- test score result --')
s.test(90)
s2.test(11)
'''
-- test score result --
Person_printPerson Dave 20
Jamie needs supplementary lessons
'''
오버라이딩(overriding)
- 부모클래스를 상속받는 파생클래스에서는 부모클래스와 동일한 이름의 메서드를 가지게 할 수 있는데, 이러한 경우엔 메서드간의 충돌이 발생하는 것이 아닌 파생클래스에서 새롭게 정의된 메서드가 부모클래스의 메서드를 대신하여 이용되며, 이러한 처리방식을
오버라이딩(overriding)
이라 부름
- 즉, 인스턴스가 파생클래스에서 정의된 인스턴스인 경우, 동일한 이름의 메서드 중 파생클래스에서 정의된 메서드가 실행된다는 뜻
- 이러한 오버라이딩은 생성자인
__init__
함수를 파생클래스에서 다시 정의하는 경우에도 적용되고, 그외에 부모클래스와 동일한 이름의 함수로 새롭게 정의하면 새롭게 정의된 함수가 실행됨을 의미함
class Person:
def __init__(self, name):
self.name = name
def getName(self):
return self.name
class Customer(Person):
def getName(self):
return "고객명 : " + self.name
person_1 = Person("홍길동")
print(person_1.getName())
'''
홍길동
'''
customer_1 = Customer("홍길동")
print(customer_1.getName())
'''
고객명 : 홍길동
'''
super()함수
- 부모클래스에서 정의한 함수와 변수를 파생클래스에서 정의한 것처럼 사용할 수 있는데, 이러한 경우 두가지 방법 중 하나를 사용해야함
부모클래스명(생성자인수).함수명()
super().함수명()
super()
함수는 부모클래스의 인스턴스를 얻는 함수로써 super().함수명()
을 통해서 부모클래스에서 정의된 해당 함수명에 정의된 변수와 기능들을 그대로 가져와서 실행시켜줄 수 있음
- 간혹
super()
함수를 부모클래스의 함수명과 파생클래스의 함수명이 중복된 경우에 사용할 수 있는 메서드라 설명하는 자료들이 있지만, 이는 정확한 표현이 아니라 생각함
- 왜냐하면
super()
뒤에 붙는 함수로 파생클래스와 중복되지 않는 다른 함수를 불러와서 사용할 수도 있기 때문에 super() 메서드는
함수를 덮어쓰는 오버라이딩(overriding)의 개념 보다는 일부 기능을 가져오는 포함(Composition)의 개념에 더 가깝다
볼 수 있음
- 쉽게 생각해서
super()
함수는 부모클래스로부터 코드를 그대로 복사해와서 코드를 간결하게 해주는 역할이라 보면 됨
- 즉, super()는 메서드 단위에서의 상속이며, 이때 상속받는 메서드의 모든 매개변수(인자)를 그대로 가져와 사용하게 되는 것!
class Person:
def __init__(self, name):
self.name = name
def getName(self):
return self.name
def printName(self):
return print(f'고객명 : {self.name}')
class Customer(Person):
def __init__(self, name, age):
super().__init__(name)
self.age = age
def getName(self):
return "고객님의 이름 : " + self.name
def getAge(self):
name = super().getName()
return f"{name}님 나이 : {self.age}"
def printAge(self):
user_name = Person(self.name).getName()
super().printName()
return print(f'{user_name}님의 나이 : {self.age}')
person_1 = Person("홍길동")
print(person_1.getName())
person_1.printName()
'''
홍길동
고객명 : 홍길동
'''
customer_1 = Customer("임꺽정", 23)
print(customer_1.getName())
print(customer_1.getAge())
'''
고객님의 이름 : 임꺽정
임꺽정님 나이 : 23
'''
customer_1.printName()
'''
고객명 : 임꺽정
'''
customer_1.printAge()
'''
고객명 : 임꺽정
임꺽정님의 나이 : 23
'''
7. 클래스의 특수 메서드
- 이번엔 고수준의 클래스 기능으로써, 클래스를 정의할 때 이미 정해져 있는 이름의 메서드인 특수메서드들을 간략하게 정리해보겠음
- 생성자인
__init__
처럼 양쪽에 2개씩의 언더바__
로 정의된 메서드이며, 이를 통해 다양한 방식으로 출력을 조절하거나 연산을 진행할 수 있으며, 기본적인 사용법은 생성자인 __init__
메서드처럼 사용하면 됨
출력 관련 특수 메서드
__str__(self)
: 내장함수 str()
에 대응함, 문자열을 반환
__format__()
: 내장함수 format()
에 대응함, 문자형의 서식을 지정하여 반환
__int__(self)
: 내장함수 int()
에 대응함, 정수를 반환
__float__(self)
: 내장함수 float()
에 대응함, 부동 소수점을 반환
__repr__(self)
: 내장함수 repr()
에 대응함, 식의 평가(eval()
)가 되는 문자열 반환
- 문자열로 객체를 다시 생성하는 함수로 쉽게 말해서 str()과의 큰 차이점은 repr()은 따옴표가 달려서 출력된다는 점
class Person:
def __init__(self, name):
self.name = name
def __str__(self):
str_ = self.name + "님"
return str_
pr = Person('임꺽정')
print(pr.name)
print(str(pr))
print(pr.__str__())
'''
임꺽정
임꺽정님
임꺽정님
'''
연산차 처리 관련 특수 메서드
- self는 왼쪽 오퍼랜드, other는 오른쪽 오퍼랜드
__add__(self, other)
: 연산자 +
에 대응함, 덧셈연산
__sub__(self, other)
: 연산자 -
에 대응함, 뺄셈연산
__mul__(self, other)
: 연산자 *
에 대응함, 곱셈연산
__truediv__(self, other)
: 연산자 /
에 대응함, 나눗셈연산
__mod__(self, other)
: 연산자 %
에 대응함, 나머지연산
컬렉션 자료형 관련 특수 메서드
__len__(self)
: len(인스턴스)
에 대응함, 길이를 반환함
__getitem__(self, 인덱스 또는 키)
: 인스턴스[인덱스 또는 키]
에 대응함, 요소 얻기
__setitem__(self, 인덱스 또는 키, 값)
: 인스턴스[인덱스 또는 키] = 값
에 대응함, 요소를 대입(할당)함
__delitem__(self, 인덱스 또는 키)
: del 인스턴스[인덱스 또는 키]
에 대응함, 요소를 삭제함
__iter__(self)
: iter(인스턴스)
에 대응함, 이터레이터를 반환함
__reversed__(self)
: reversed(인스턴스)
에 대응함, 역순의 이터레이터를 반환함
요약 및 마무리
- 이 글에서는 객체지향프로그래밍의 개념과 클래스에대해서 다루어보았음
OOP
- 프로그래밍의 3가지 패러다임
- Procedural Programming (절차형, 순서형 프로그래밍)
- Functional Programming (함수형 프로그래밍)
- Object Oriented Programming (객체지향 프로그래밍)
- OOP : 기능별로 수행하며, 데이터(속성)와 메서드(처리)를 함께 사용할 수 있는 구조로 프로그래밍 하는 방법, 주로 Class를 통해 구현되고, 클래스 선언 순서에 관계없이 실행할 수 있음
Class
- Class (클래스) 정의하기
- 변수, 함수 등을 함께 기술할 수 있음
- Class명의 첫문자는 대문자로 설정하는 것이 국룰
- self의 의미는 인스턴스와 관련되어 있음을 의미함
- 인스턴스(instance) : 클래스로부터 생성되는 각각의 존재를 의미, 메소드나 속성을 이용하려면
.
을 통해 접근
- 인스턴스 변수 :
self.변수
- 인스턴스 메서드 :
def 메서드(self):
- 생성자(
__init__
) : 초기값 및 초기화 메서드, 인스턴스 생성시 실행됨
- 클래스 메서드는 데코레이터(
@classmethod
)를 통해 정의
- 캡슐화(capsulization) : 데이터를 안전하게 유지하고, 외부로부터 마음대로 접근할 수 없도록 하는 것
- 상속(inheritance) : 새롭게 확장한 클래스가 기존의 클래스의 속성과 메서드를 물려받는 것
- 속성과 메서드를 물려주는 기존 클래스 :
기저클래스
혹은부모클래스
- 속성과 메서드를 상속받는 새로운 클래스 :
파생클래스
혹은자식클래스
- 포함(Composition) : 클래스의 일부 변수와 기능만 가져오는 것
- 오버라이딩(overriding) : 부모클래스와 동일한 이름의 메서드를 가지는 경우 새롭게 정의된 메서드가 부모클래스의 메서드를 대신하여 이용되는 것
- super() 함수 : 부모클래스로부터 메서드 단위로 상속을 받는 것, 이때 상속받는 메서드의 모든 매개변수(인자)를 그대로 가져와 사용함
- 오버라이딩(overriding)의 개념 보다 포함(Composition)의 개념에 더 가까움
마무리
- 다소 내용이 많아지고 복잡해졌지만, 클래스는 많이 써보고 익숙해지는 것이 가장 중요하다 생각함
- 이후에 추가적인 학습을 통해 보완하거나 추가할 내용이 생기면, 업데이트를 지속적으로 해나갈 예정임
- 화이팅!