Abstraction
추상화 : 가장 중요한 속성만 포함하는 entity(개체)의 view or representation (관점 or 표현)
추상화 개념은 프로그래밍과 컴퓨터 과학에서 중요한 개념이다.
거의 모든 프로그래밍언어는 subprogram을 통한 프로세스 추상화를 지원한다. Process abstraction
1980년 이후로 설계된 거의 모든 프로그래밍언어는 데이터 추상화를 지원한다. Data abstraction
객체지향 언어
- Simula-67 : 실세계에 있는 객체들을 표현, 이들 사이의 상호작용을 시뮬레이션하기 위한 언어. 클래스 개념 도입
- Smalltalk : 순수한 객체지향 언어로 설계, 최초로 GUI를 제공하는 언어
- C++ : C에 클래스 개념 도입 / 상속, 가상함수, 추상 클래스, 예외 처리 등 다양한 기능 추가
Static function binding - Java : 단순성, 플랫폼 독립성 / 객체지향 패러다임에 충실하게 고안, C++보다 오용의 소지가 적음
Dynamic function binding / 웹 애플리케이션과 모바일 앱 개발 등의 분야에서 많이 사용 - Objective-C : C와 객체지향 언어를 혼합 / C++보다는 Smalltalk에 더 가깝게 정의된 언어 / Swift로 발전
- C# : MS에서 개발한 객체지향 언어 / 닷넷 프레임워크의 한 부분 / 문법적 특성이 C++보다 Java와 유사
- Python : 플랫폼 독립적 / 동적 타이핑을 지원하는 대화형 인터프리터 언어 / 객체지향 개념을 포함한 다중 패러다임 언어
객체와 클래스
- 클래스는 객체의 정의 혹은 타입
- 객체는 어떤 클래스 타입으로 선언
- 객체는 어떤 클래스의 실체(instance) (메모리에 올라오는 것) (object)
실체화(Instantiation)
- 클래스로부터 객체를 생성하는 것 (Java와 C++의 ‘new’ 키워드) (메모리를 차지하는 과정)
- C++ : MyClass A : 선언 자체가 instance를 stack에 만든다. (local 변수라면) (선언함과 동시에 메모리에 생성)
- * A : 명시적으로 new를 통해서 생성자를 호출할 때 메모리에 생성된다. (run-time에 할당하는 heap 변수)
- Java : 반드시 new를 사용. 선언할 때는 주소 공간만 할당. new를 통해서 실제 객체를 생성
- Python : 생성자를 호출하는 순간 run-time에 메모리를 할당
프로그램 : 클래스들의 집합
프로그램 실행 : 서로 상호작용하는 객체들의 집합 (a set of objects invoking each other methods)
Abstraction
다음 두 가지 조건을 만족하는 user-defined data type
- Information Hiding : type의 객체 표현은 이 객체를 쓰는 프로그램 유닛으로부터 숨겨진다. 그러므로 type의 정의가 제공된 곳에서만 작동이 가능하다.
- Single Syntactic unit : type의 선언과 객체에 대한 동작 프로토콜이 하나의 문법적 단위에 포함되어 있다. 다른 프로그램 유닛들은 정의된 type의 변수들을 생성하는 것이 허락된다.
Class는 ADT의 한 예시
C의 Struct는 2번은 해당하지만 1번은 해당 X
Information Hiding의 장점
- Reliability : 데이터 표현을 숨김으로 user code는 type의 객체에 직접 접근하거나 표현에 의존할 수 없다. user code에 영향을 끼치지 않고 표현을 바꿀 수 있다.
- 프로그래머가 인식해야 하는 코드와 변수의 범위를 줄인다.
- 이름 충돌이 줄어든다.
Single Syntactic unit의 장점
- 프로그램 조직 방법을 제공한다. (구조화된다.)
- Modifiability를 도와준다. (수정 가능성을 도와준다. = data structure와 관련된 모든 것이 함께 있다.)
- 컴파일이 분리된다. (Class를 별도의 파일에 만들 수 있기 때문)
ADT를 위한 언어의 요구사항
- type 정의를 캡슐화할 수 있는 syntactic unit
- 실제 정의를 숨기면서 type name과 subprogram header를 client에게 보이게 만드는 방법
- 언어 프로세스에 몇몇 primitive operation이 있어야 한다. (기본 연산 : assign_대입 + comparative_비교)
C++
C의 Struct와 Simula-67의 클래스를 기반으로 한다.
클래스는 캡슐화를 해주는 장치이다. (Encapsulation device)
클래스는 type이다.
클래스의 모든 class instance는 하나의 member function(멤버 함수) copy를 공유한다.
클래스의 각 instance는 각자의 class data member copy를 가지고 있다.
Instance는 static, stack-dynamic, heap이 가능하다.
(static : 글로벌로 선언, static 키워드 사용) (stack-dynamic : 일반적인 상황) (heap : 포인터로 선언, new 키워드)
Information Hiding (접근 지시자)
- Private : entity에 나만 접근할 수 있다.
- Public : 모두가 접근할 수 있다.
- Protected : 나한테서 파생된, 상속된 클래스들만 접근할 수 있다.
Constructor (생성자)
- instance의 데이터 멤버를 초기화해주는 함수
- 객체의 일부가 heap-dynamic이라면 필요에 따라 저장소를 할당할 수 있다.
- 객체의 parameterization을 제공하기 위해 parameter를 포함할 수 있다.
- instance가 생성될 때 암묵적으로 호출된다.
- 명시적으로도 호출할 수 있다.
- 이름은 클래스의 이름과 같아야 한다.
Destructor (소멸자)
- instance가 파괴된 후 정리를 해주는 함수. 일반적으로 heap 저장소를 회수하는데 사용된다.
- 객체의 lifetime이 끝나면 암묵적으로 호출된다.
- 명시적으로도 호출할 수 있다.
- 이름은 클래스 이름 앞에 ~을 붙인 형태이다.
Friend function / Friend class
- private member에 대한 접근을 관련이 없는 유닛이나 함수에게 제공한다.
JAVA
C++과의 차이점
- 모든 객체가 heap에 생성된다. reference 변수를 통해 접근한다.
- 클래스의 개별 entity가 access control modifier를 가진다. (private, public 등)
- 암묵적인 garbage collection이 이루어진다. (= 소멸자가 필요 없다.)
- second scoping mechanism = package scope이 있다. friend 대신에 사용할 수 있다.
- 패키지의 모든 클래스의 access control modifier가 없는 모든 entity는 패키지 전체에서 볼 수 있다.
Python
- __init__ 메소드 : 객체 초기화
- 객체의 실체 변수(속성) : 별도 선언 없이 바로 사용
- self : 자신 객체를 나타내며 “self.변수이름”은 객체의 실체 변수를 나타냄
- 객체 변수 : 각 객체마다 기억공간이 할당되는 실체 변수 (instance variable)
- 클래스 변수 : 클래스에 하나 존재하여 그 클래스의 모든 객체가 공유하는 정적 변수
접근 지정자 없이 작명법으로 제어
- public
- _ _ private
- _ protected
Parameterized ADT
Parameterized ADT는 어떤 유형의 type도 저장할 수 있도록 디자인된 ADT이다.
(static typed 언어에서는 문제가 된다.)
Generic class라고도 불린다.
C++과 Java는 지원한다.
Encapsulation Constructs
대규모 프로그램은 두 가지 특별 요구사항이 있다.
- 단순히 subprogram으로 나누는 것 외의 조직 수단이 필요하다.
- 부분적인 컴파일 수단이 필요하다. (전체 프로그램보다 작은 컴파일 단위를 컴파일 가능해야 한다.)
=> 해결책 : 논리적으로 연관된 subprogram을 부분적으로 컴파일할 수 있도록 unit으로 그룹핑한다.
= compilation units / 이러한 collection을 encapsulation = 캡슐화라고 한다.
C에서의 캡슐화
- 하나 이상의 subprogram을 포함하는 파일은 독립적으로 컴파일될 수 있다.
- 인터페이스는 header file에 위치한다.
- #include 전처리기 지시문을 통해서 애플리케이션에 header file을 포함시킨다.
- 문제1 : linker는 헤더와 연관된 implementation 사이의 type을 체크하지 않는다.
- 문제2 : 포인터와 관련된 내재된 문제가 있다.
C++에서의 캡슐화
- C처럼 header file과 code file을 정의해서 사용
- 클래스를 이용
Naming Encapsulations
대규모 프로그램은 많은 global name을 정의한다. -> 논리적인 grouping 으로 나누는 방법이 필요
naming encapsulation은 name의 새로운 scope를 생성하는데 사용한다.
C++ Namespaces
- 각 라이브러리를 그것의 고유한 namespace에 위치시키고, 외부에서 사용되는 이름을 namespace로 한정
Java Packages
- 패키지는 하나 이상의 클래스 정의를 포함한다.
- 패키지 내부의 클래스는 부분적인 friend이다
'Programming Languages [PL]' 카테고리의 다른 글
[PL] 12. Exception Handling and Event Handling (0) | 2024.01.10 |
---|---|
[PL] 11. Support for Object-Oriented Programming (1) | 2024.01.10 |
[PL] 09. Implementing Subprograms (1) | 2024.01.10 |
[PL] 08. Subprograms (0) | 2024.01.10 |
[PL] 07. Statement-Level Control Structures (0) | 2024.01.10 |