-------------------------
05.OOP
-------------------------
//
OOP와 AOP의 특징 : https://greendreamtrre.tistory.com/601
OOP(Object Oriented Programming, 객체지향 프로그래밍) : 모든 데이터를 현실에 빗대어 객체로 다루는 프로그래밍 기법이다.
객체지향 언어의 5가지 특징은 다음과 같다.
1. 캡슐화 (Encapsulation) : 데이터와 함수를 하나로 묶는다.
2. 정보은닉 (Information Hiding) : private로 선언한 데이터는 자기 자신을 통해서만 접근(setter, getter)이 가능하다.
3. 추상화 (Abstraction) : 불필요한 부분은 생략하고 중요한 것에만 초점을 맞춰 모델로 만든다.
4. 상속성 (Inheritance) : 상위 클래스에 정의된 모든 것을 하위 클래스가 물려받는다.
5. 다형성 (Polymorphism) : 호출하는 객체에 따라 다른 동작을 한다.
AOP(Aspect Oriented Programming, 관점지향 프로그래밍) : OOP를 더욱 발전시키기 위한 개념이다.
하나의 소프트웨어가 하나의 거대한 OOP로써 설계, 프로그래밍 되었다면 이것을 각 기능별로 모듈화 해서 분리를 시키는 개념이다.
//
** OOP(Object Oriented Programming - 객체지향 프로그래밍)
1. 개요
1) 3대 특징
=> Encapsulation(캡슐화)
불필요한 정보는 숨기고 중요한 정보만을 표현해서 프로그램을 간단하게 만드는 것
(인터페이스를 간단하게 만드는 것)
=> Inheritance(상속성)
하위 클래스가 상위 클래스의 모든 요소를 물려받는 것
=> Polymorphism(다형성)
동일한 메세지에 대하여 다르게 반응하는 성질
2) 용어
=> Object(객체) : 프로그램에 사용되는 모든 것
=> Class : 사용자 정의 자료형
동일한 목적을 달성하기 위해 모인 속성(데이터)과 메서드(기능 - 함수)의 집합
정적(static): 한번 만들면 변경되지 않는
-> 일반적으로 클래스 이름을 대문자로 시작하고 변경할 생각이 없는 데이터의 이름은 모두 대문자로 만드는 것이 관례이다.
=> Instance : Class를 기반으로 메모리 할당을 받은 객체
동적(dynamic): 변경 가능한
=> Class Object : Class를 의미
=> 정적바인딩과 동적바인딩
정적바인딩은 실행 전에 결정되는 것 - 변수를 만들 때 자료형을 명시적으로 작성하거나 암묵적으로 결정해두고 사용하기 때문에 실행 중에 변수에 다른 종류의 데이터를 삽입할 수 없음
동적바인딩은 실행 중 결정 가능한 것 - 참조형 데이터만 존재하고 변수는 데이터의 참조를 저장하기 때문에 실행중에도 다른 종류의 데이터를 대입할 수 있음.
-> 정적바인딩은 준비를 해놓고 시작하기 때문에 속도가 빠르고 컴파일 오류의 가능성이 줄어든다.
=> 속성(attribute) : Instance를 구성하는 데이터
=> method : Class 안에 만들어진 기능(함수)
=> property : 속성처럼 사용하는데 실제로는 method를 호출하는 것
=> record나 sturcture(구조체) : 하나의 행을 의미, Instance를 구성하는 속성의 집합
=> python의 모든 데이터는 기본적으로 instance
=> Information Hiding(정보 은닉) :불필요한 부분을 숨기는 것
2. Class 와 Instance
1) 클래스 생성
class 클래스이름:
초기화 메서드 생성
메서드 생성
2) 인스턴스 생성 (인스턴스 : 속성과 클래스에 대한 참조)
=> 인스턴스 이름 = 초기화 메서드(매개변수) -> 초기화 메서드의 이름은 클래스 이름
=> 인스턴스를 생성하는 메서드를 호출하면 인스턴스를 생성하고 그 참조를 리턴
3) 인스턴스나 클래스를 이용한 멤버 호출
인스턴스나 클래스.속성
인스턴스나 클래스.메서드(매개변수)
4) Method
=> 인스턴스가 있어야만 호출되는 메서드와 인스턴스가 없어도 호출되는 메서드(static, class)로 구분
=> 인스턴스가 있어야 하는 메서드 생성
def 메서드이름(인스턴스 참조를 저장할 매개변수, [매개변수 나열]):
내용
관례상 인스턴스 참조를 저장할 매개변수의 이름은 self
=> 인스턴스가 있어야 하는 메서드 호출
클래스이름.메서드이름(인스턴스이름, 매개변수) : Unbound 호출
인스턴스이름.메서드이름(매개변수) : Bound 호출
클래스 내부의 다른 메서드에서 호출 : self.메서드이름(매개변수)
1), 2), 3), 4)의 ex.
# 클래스 생성
# class 클래스이름:
class Student:
# 인스턴스가 있어야만 호출되는 메서드 생성
# def 메서드이름(self, 매개변수): # 첫 번째 매개변수인 인스턴스 참조를 저장할 매개변수의 이름은 self를 주로 사용한다.
def disp(self):
print("인스턴스 생성")
# 인스턴스 생성
# 인스턴스 이름 = 클래스 이름(매개변수)
student = Student()
# -> 여러 번 사용할 때 편리하게 쓰기 위해서 Bound 호출을 선택하였다.
# -> 한 번만 사용하는 것이라면 Bound 호출이 아니라, Unbound 호출을 이용해 클래스를 곧바로 써도 된다.
# 메서드 호출 - bound 호출
student.disp()
# 메서드 호출 - Unbound 호출
Student.disp(student)
5) 인스턴스의 속성 만들기
=> 파이썬에서 인스턴스의 속성을 만들고자 하는 경우에는 인스턴스가 있어야 호출되는 메서드 안에서 self.속성명으로 데이터를 대입하면 만들어집니다.
메서드 안에서 self.을 이용하지 않고 만든 속성은 지역 변수가 됩니다.
=> 클래스 외부에서 "인스턴스.속성이름 = 데이터"를 작성하면, 속성이 존재할 때 속성의 값을 변경하는 것이고 속성이 존재하지 않으면 속성이 생성됩니다.
class Student:
def setName(self, name):
self.name = name # 지역 변수가 아니라 인스턴스의 속성을 생성
# 인스턴스 생성
stu = Student()
stu.setName("파이터")
print(stu.name)
stu.score = 94 # 인스턴스에 score라는 속성이 있으면 수정, 없으면 생성
print(stu.score)
6) Class 속성
=> class 내부 그리고 method 외부에 변수를 생성해서 데이터를 대입하면 class 속성이 됩니다.
=> class의 속성은 클래스와 인스턴스 모두 접근이 가능합니다.
인스턴스를 이용해서 접근할 때 그 속성이 인스턴스 내부에 없으면 class 속성을 호출하지만 인스턴스 내부에 존재하면 인스턴스의 속성을 호출합니다.
즉 대입문을 이용하면 인스턴스의 속성을 생성해서 사용합니다.
클래스 속성은 인스턴스를 이용해서 접근하는 것을 권장하지 않습니다.
class Student:
class_data = "클래스의 속성"
student = Student() # 인스턴스를 생성할 때는 이처럼 클래스이름을 호출한다.
print(Student.class_data) # 클래스이름을 이용해서 클래스 속성에 접근
print(student.class_data) # 인스턴스이름을 이용해서 클래스 속성에 접근
Student.class_data = "클래스 데이터 수정" # 클래스이름으로 클래스 속성 수정
print(Student.class_data) # 클래스이름을 이용해서 클래스 속성에 접근
print(student.class_data) # 인스턴스이름을 이용해서 클래스 속성에 접근
student.class_data = "인스턴스를 이용해서 클래스 데이터 수정" # 인스턴스이름으로 클래스 속성 수정
print(Student.class_data) # 클래스 이름을 이용해서 클래스 속성에 접근
print(student.class_data) # 인스턴스 이름을 이용해서 클래스 속성에 접근
# -> 클래스(Student)에는 class_data라는 속성이 존재하지만, 인스턴스(student)에는 존재하지 않아서 새로 생성된다. 따라서 출력 결과가 다르게 나타난다.
***** 정리
-> 똑같은 속성으로 이루어진 것들을 Class로 만들고 그 안에서 똑같지 않은, 다른 것들을 Instance로 구분한다.
클래스에서 만든 속성은 클래스나 인스턴스 모두로 접근할 수는 있지만, 일반적으로 클래스에서 접근하는 것이 더 좋다. (파이썬에서만 가능하다.)
인스턴스로 접근하는 것은 상당히 비효율적이다. (데이터가 존재하지 않으면 한 바퀴 돈다.)
-> 클래스는 첫 글자를 대문자로 인스턴스는 첫 글자를 소문자로
-> Java나 C++은 인스턴스 참조를 저장할 매개변수로 self 대신에 this를 사용한다.
-> 속성은 각자 가지고 있지만 메서드는 공유합니다.
-> 클래스는 바로 줄 수 없으므로 인스턴스로 만들어야 한다.
인스턴스를 이용하면 생성하지 않은 것도 만들 수 있다.
깨알) 1, 2, 3과 같은 숫자는 int 클래스에 속하고, x = 1이라 하면, int 클래스를 통해 x라는 인스턴스를 생성하는 것이다.
7) is 연산자
=> python의 변수는 데이터를 저장하고 그 데이터의 id를 저장하는 개념
=> == 연산자는 목적이 id를 비교하는 것이 아닙니다.
파이썬에서 == 연산자는 내부에 만든 __eq__ 메서드를 호출해서 그 결과를 리턴하는 연산자입니다.
== 연산자는 오버로딩(기능을 변경)이 가능하기 때문에 어떻게 동작할지 예측하기 어렵습니다.
=> id를 비교하는 연산자는 is 연산자 입니다.
is 연산자는 오버로딩이 안되기 때문에 명확하게 id를 비교한다고 할 수 있습니다.
class Student:
class_data = "클래스의 속성"
# 인스턴스를 생성해서 대입
stu1 = Student()
# 인스턴스를 생성해서 대입
stu2 = Student()
# stu1의 데이터를 대입 : stu1이 참조하고 있는 데이터의 참조를 stu3가 참조합니다.
stu3 = stu1
# 2개의 인스턴스가 동일한지 여부를 확인
print(stu1 == stu2) # 내부의 데이터가 같은지 확인
print(stu1 is stu2) # id가 같은지 확인
# -> 인스턴스는 속성이나 클래스에 대한 참조를 가져오는 것이기 때문에,
# stu1과 stu2는 서로 다른 인스턴스로 각각 다른 참조를 나타내기(가리키기) 떄문에 위의 두 결과에 대해서 False가 나오게 된다.
print(stu1 == stu3) # 내부의 데이터가 같은지 확인
print(stu1 is stu3) # id가 같은지 확인
# -> stu3은 stu1의 참조를 그대로 받아오므로 위의 두 결과에 대해서 True가 나오게 된다.
8) Accessor - 접근자 메서드
=> 객체지향 언어에서는 인스턴스를 가지고 속성에 직접 접근하는 것을 권장하지 않습니다.
=> 속성에 접근하는 메서드를 이용해서 속성의 값을 가져다가 사용하고 수정하도록 합니다.
속성의 값을 리턴하는 메서드를 getter라고 하고 속성의 값을 수정하는 메서드를 setter라고 합니다.
=>getter
이름은 get속성이름으로 하고 매개변수는 일반적으로 없고 속성을 리턴하기만 합니다.
속성의 자료형이 bool인 경우 get 대신에 is를 붙입니다.
속성의 이름의 첫글자는 대문자로 표기하는데 파이썬에서는 대문자 대신에 _를 사용하는 경우가 있습니다.
=>setter
이름은 set속성이름으로 하고 매개변수는 속성과 동일한 자료형의 데이터 1개로 생성
내용은 매개변수로 받은 데이터를 속성에 대입합니다.
=> 속성의 자료형이 Sequence(list)인 경우
인덱스를 받아서 인덱스 번째 데이터를 리턴하는 getter를 추가로 생성하고 인덱스와 데이터 1개를 받아서 인덱스 번째 데이터를 수정하는 setter를 생성하기도 합니다.
# 이름과 점수를 갖는 객체를 여러개 필요로 하는 경우
class Student:
def getName(self):
return self.name
def setName(self, name):
self.name = name
def getScore(self):
return self.score
def setScore(self, score):
self.sore=score
stu1 = Student()
# setter를 이용한 속성 생성과 설정
stu1.setName("반승현")
stu1.setScore(99)
# getter를 이용한 속성 사용
print(stu1.getName())
print(stu1.getScore())
# 최근에 등장한 IDE는 대부분 getter와 setter를 만드는 유틸을 제공합니다.
//
1. 클래스를 부여하면 인스턴스를 생성할 수 있어야 하고,
2. 메서드도 호출할 수 있어야 한다.
#python
'Python' 카테고리의 다른 글
05.OOP(2) (0) | 2023.08.17 |
---|---|
04.Function(2) (0) | 2023.08.16 |
04.Function(1) (0) | 2023.08.05 |
03.Control Statement (0) | 2023.08.05 |
02.Variable_Operator (0) | 2023.08.05 |