Part3) CH6. OOP와 캡슐화

songtofu·2022년 12월 5일
0

전문가를 위한 C

목록 보기
6/10

앞서

  • C에서 객체지향 프로그램을 작성할 수 있는 이유?
    -> 간접적인 방식으로는 객체지향 개념을 지원한다. 사실상 거의 모든 컴퓨터 언어는 OOP를 지원. (자료형을 확장하는 방법 존재하고 이것이 OOP로 향하는 첫걸음임)

    OOP?
    - object-oriented programming(OOP) 객체 지향 프로그래밍

  • OOP는 문제를 생각하고 분석하는 방식에 가까우며, 인간이 항상 채택했던 것과 같은 관점을 적용함.

6.1) 객체지향적 사고

6.1.1.정신적 개념

  • (기술 관련 주제) 개념? 주제 와 관련해 이해해야 하는 원리

6.1.2. 마인드맵과 객체 모델

ex. 문장을 읽고 어떤 장면을 떠올릴 때 사람마다 다르게 떠올릴 수 있음 = 모든 사람이 다른 방식으로 그릴 수 있음.

  • 문제에 달려들기 전 마인드 맵을 만든다 = 이해 단계
  • 개념 = 객체, 마음 = 메모리, 마인드 맵 = 객체 모델

6.1.3. 코드에는 없는 객체

  • 실행 중인 프로그램이 있어야지만 객체가 존재한다.

    객체지향 코드를 작성할 때는 아직 아무 객체도 존재 X. 객체는 코드를 빌드해서 실행 가능한 프로그램을 만들고 프로그램을 실행해야 비로소 만들어진다.

  • OOP는 객체를 실제로 만들지 않는다. 프로그램이 실행될 떄 완전히 동적인 객체모델로 이어질 일련의 명령어를 만든다. 일단 컴파일 및 실행이 되면 객체지향 코드는 객체를 만들고, 수정하고, 연결하고, 삭제까지 할 수 있어야함.
  • 아직 만들어지지 않으 ㄴ것에 관한 다양한 세부 사항을 설명하고 제작하는 기술 = 설계 (객체 지향 프로그래밍에서 객체 지향 설계(OOD)라고 함)
  • 객체지향 코드에서는 객체를 생성할 계획만 세울 수 있음.
  • OOP 언어는 다양한 객체지향 작업을 작성하고 계획할 수 있도록 하는 일련의 명령어(와 문법 규칙)를 갖는 언어.
  • 모든 객체는 지정된 생명 주기를 가짐.
  • 불변 객체는 함수형 프로그래밍 패러다임이라는 제목으로 설명 ex.숫자 2

6.1.4. 객체 속성

  • 객체는 두개 이상의 속성 또는 속성의 집합을 가질 수 있다.
  • 속성에 할당된 값을 총괄해 객체의 상태라고 함.
  • 상태? 단순히 객체에 연결된 특정 속성에 속하는 값의 목록. 수명동안 수정될 수 있음. (== 가변객체), 상태가 없을 수도 있음.(객체가 어떠한 상태 ㄸㅎ는 속성을 가지지 않음) , 불변일 수 도 있음.(ex.숫자 2)

    상태가 없는 객체는 수명 동안 상태를 변경할 수 없으므로 불변 객체로 간주.

  • 불변 객체 중요! 상태가 변경될 수 없다는 것은 장점이다. 특히 멀티스레드 환경에서 불변 객체가 공유될 때 그렇다. (Thread-safe하여 병렬 프로그래밍에 유용하며, 동기화를 고려하지 않아도 된다.)
    +) https://steady-coding.tistory.com/559

6.1.5. 도메인

  • 도메인? 소프트웨어가 기능을 공개할 경계를 정의. 소프트웨어가 다루어야 하는 요구 사항을 정의

6.1.6. 객체 사이의 관계

  • 객체는 관계를 나타내고자 서로를 참조할 수 있음.
  • 객체를 연관시키려면 객체의 관계를 나타내는 추가 속성이 필요.
  • 관계가 두 객체 사이에 형성된다면, 이 객체의 상태(혹은 속성에 해당하는 값의 목록)는 변경된다. 이는 당연히 객체의 가변성 또는 불변성에 영향이 잇음.
  • 객체의 상태 및 불변성을 정의하는 속성의 부분집합은 한 도메인에서 다른 도메인으로 변경될 수 있으며, 이러한 속성의 부분집합은 모든 속성을 반드시 포함하지는 않는다.
    ex. 한 도메인 -> x,y,red,green,blue(비참조형). 다른 도메인-> adjacent_up_pixel(참조형 속성)

6.1.7. 객체지향 작업

  • OOP 언어는 곧 실행될 프로그램에서 객체의 생성, 소멸, 상태 변경을 계획할 수 있도록 한다.

    creation = 객체의 메모리 할당
    construction = 속성의 초기화

  • 객체의 생성을 계획하는 두가지 방법
  1. 빈 객체(속성X) 생성하거나 또는 더 일반적으로 최소한의 속성의 집합을 갖는 객체를 생성하는 것. == 프로토타입 기반의 OOP (ex. JS, Ruby, Ptyhon, Pearl, PHP)
    • 코드가 실행되는 동안 더 많은 속성이 결정되고 추가된다. 주변 환경에서 발견되는 변경 사항에 따라 같은 프로그램을 다르게 두 번 실행할 때, 같은 객체라도 다른 속성을 가질 수 있음.
    • 각각의 개체느 ㄴ별도의 개체로 취급. 어떤 두 객체가 공통 속성의 목록을 가져서 같은 그룹(혹은 클래스)에 속하는 것 처럼 보여도 두 객체는 프로그램이 지속되는 동안 상태에 다른 속성을 갖는다.
    • 대다수 인터프리터 프로그래밍언어.
  2. 속성이 미리 정해져 있어서 실행 도중에 변경되지 않는 객체를 생성 == 클래스 기반 OOP(ex.Java, C++,Python)
    • 런타임 동안 어떠한 속성도 추가되지 못해 객체는 구조를 유지. 속성값만 변경 가능 . 객체가 가변적일 때만 가능.
    • 개발자는 런타임 때 객체에 존재해야하는 모든 속성을 추적하는, 미리 설계된 객체 템플릿 또는 클래스를 만들어야함. 이 템플릿을 컴파일 해서 런타임 시에 객체지향언어로 제공해야함.
  • 객체와 인스턴스는 같은 것. 서로 바꿔 사용 가능. (어떤 글에서는 약간의 차이 가능)

  • 참조? 객체를 참조하는 포인터와 같다. 같은 객체를 참조하는 여러 참조 있을 수 있다. 객체는 이름이 없지만 참조는 이름이 있음.

    C에서는 참조에 대응하는 문법으로 포인터가 있다.

  • 실존주의는 프로토타입 기반의 접근법과 매우 가까움.

  • 객체가 살아 있는 동안 할당한 모든 리소스는 객체가 파괴될 때 해제 되어야함. 객체가 파괴될 때 다른 모든 관련된 객체도 파괴된 객체를 더 이상 참조하지 않도록 변경되어야함.

  • 객체는 존재하지 않는 객체를 참조하는 속성을 가질 수 없다. 만약 그럴 경우 객체 모델에서 참조 무결성을 잃는다. 이는 메모리 손상, 세그멘테이션 오류, 오산

6.1.8. 행위를 갖는 객체

ex. 고객, 계좌, 생성 O but, 고객, 계좌, 먹음 X

6.2) C가 객체지향이 아닌 이유

  • 객체지향(인간)과 절차지향(CPU) 프로그래밍 사이를 가르는 장벽에 위치.
  • 모든 환경은 반드시 객체지향적이지는 않지만, 고수준 로직을 저수준의 절차지향적 명령어로 변환하는 레이어가 필요
    ex. Java 플랫폼에서는 JVM(자바 가상 머신)

6.3) 캡슐화

  • 객체는 객체에 추가된 속성의 집합 및 기능의 집합.
  • 객체라는 개체에 넣는 작업을 설명 (캡슐화 라는 과정을 통해 수행)
  • 캡슐화? 객체를 나타내는 캠슐에 서로 연관된 것을 집어넣는다는 의미
  • 객체는 속성의 집합 그리고 기능의 집합. 속성과 기능은 둘 다 객체 캡슐로 캡슐화 되어야함.

6.3.1. 속성 캡슐화

-명시적 캡슐화? 개발자와 프로그래밍 언어 둘 다 캠슐화, 캠슐의 존재를 안다는 의미

런타임이 아닌 컴파일할 때 오류를 잡아낼 수 잇다는 것은, 인간의 객체지향적 사고방식을 제대로 인지하는 객체지향적 언어의 주요 이점.

6.3.2. 행위 캡슐화

  • 객체란 속성과 메서드의 캡슐
  • 메서드? 객체 내에 저장되는 로직 또는 기능을 나타내고자 사용하는 표준 용어
  • 메서드는 C의 함수로 간주 이름, 인자의 목록, 반환형을 가짐.
  • 속성은 값을 전달. 메서드는 행위를 전달 그러므로 객체는 값의 목록을 갖고 시스템에서 어떤 행위를 수행할 수 있음.
  • 암묵적 캡슐화의 기법 p.275참고

6.3.3 정보 은닉

  • 캡슐화의 목적 또는 결과
  • 정보 은닉은 외부 세계(객체의 행위에 속하지 않는 모든 코드)에 보이지 않아야하 하는 어떠한 속성이나 행위를 보호하는 역할.
  • 해당 속성이나 행위가 클래스의 공용 인터페이스에 속하지 않으면, 이 정의에 의해 다른 코드나 다른 C함수는 객체의 비공개 속성이나 행위에 접근 할 수 없음.
    ex. 자동차 가속 행위 = 공개 API or 공용 인터페이스
  • 일반적으로 객체를 사용하는 코드는 그 객체의 공개 속성과 행위에 의존적.
    -> 내부 속성을 공개 속성으로 선언해 유출한 뒤 비공개로 바꾸면 종속된 코드의 빌드가 깨짐. 공개된 속성을 사용하는 코드는 해당 속성이 비공개가 되면 변경된 이후 컴파일되지 않음. 이는 하위 호환성이 손상되었음을 의미.
    그러므로, 보수적인 접근법을 취하며, 속성을 공개로 두어야 할 합리적인 이유를 찾을 때까지 기본적으로 모든 속성을 비공개로 둔다.
  • 클래스의 비공개 코드를 노출한다는 것 = 가벼운 공용 인터페이스가 아닌, 길게 서술된 구현에 의존적

    비공개 행위 함수에 다른 표현법을 사용할 수 있다. 이름에 접두어 __를 사용

$ gcc main.o private.o -o ex6_3.out

private.o에 비공개 부분을 정의하고 링크해 실행

  • 새로운 리스트 구현에 관한 경우 매번 링크 단계를 반복하고 싶지 않을 때
    비공개 목적 파일을 포함하는 공유 라이브러리(또는 .so파일)을 사용
profile
읽으면 머리에 안들어와서 직접 쓰는 중. 잘못된 부분 지적 대환영

0개의 댓글