23.02.06.(월) - 객체지향 프로그래밍

김도익·2023년 2월 6일
0

C#

목록 보기
24/29

오늘은 받아들이는 영역입니다.
'암기'하세요. 그래야 훗날 '이해'가 됩니다.

객체지향적 프로그래밍은 '확장성'과 '유지보수'가 목표입니다.
'확장성'과 '유지보수'가 안된다면 그건 객체지향 프로그래밍이 아닙니다.

개요

객체지향 프로그래밍(OOP : Object-Oriented Programming)은 현대 프로그래밍 패러다임 중 가장 주류가 된 프로그래밍 패러다임입니다.

캡슐화

  • 절차지향 프로그래밍 언어에서는 어떤 타입을 설계할 때, 데이터만 정의할 수 있었습니다.

  • 그리고 데이터를 프로그래머가 마음대로 외부에서 조작할 수 있는 것도 실수할 여지가 있었습니다.

  • 그래서 객체지향 프로그래밍에서는 데이터와 데이터를 다루는 함수를 같이 작성할 수 있게 했으며, 이를 캡슐화(Encapsulation)라고 합니다.
    객체를 올바르게 사용할 수 있도록 접근 한정자를 제공해 외부에 공개할 것과 그렇지 않은 것을 구분짓게 했습니다.
    이를 데이터 은닉(Data Hiding)이라고 합니다.

  • 객체지향 프로그래밍에서 데이터 부분을 필드, 함수를 메소드라고 합니다.
    즉, 캡슐화란 데이터랑 함수를 같이 쓸 수 있게 만들어 준것입니다.

상속(Inheritance)

  • 상속은 코드를 물려 받는 기능으로 코드를 재사용할 수 있게 합니다.
    상속을 이용하면 더 작은 단위로 모듈화를 할 수 있습니다.

  • 부모 클래스는 두 개가 될 수 없습니다.
    즉, 단일 상속만 가능합니다.

  • 자식 클래스에서는 부모 클래스의 private 멤버를 제외하고 접근할 수 있습니다.
    하지만 필드는 자식에게도 공개하지 않는 것이 좋은 설계입니다.

생성 순서

  • 자식 클래스 객체를 생성할 경우 생성 순서는 부모 – 자식 순입니다.
    소멸은 자식에서부터 부모 순입니다.

sealed 클래스

  • 어떤 경우에는 상속을 막고 싶을 때도 있을 것입니다. 이 경우 sealed 한정자를 사용합니다.

다형성(Polymorphism)

  • 많은 형태를 가지고 있다. 라는 한문 뜻입니다.

  • 다형성은 객체지향에서 핵심입니다.

  • 다형성은 같은 인터페이스로 서로 다른 동작을 하게 됩니다.
    다형성은 객체지향의 핵심으로, 조건문을 암시적으로 만들어 프로그램을 확장할 때 큰 변화를 들이지 않아도 된다는 장점이 있습니다.
    가령 캐릭터가 갖고 있는 직업군에 따라 줄 수 있는 물리 데미지가 다르다고 해보겠습니다.

<관련 문법>

업캐스팅과 다운캐스팅

  • 자식 클래스 타입의 인스터스는 부모 클래스 타입의 변수에 저장할 수 있습니다.
    이를 업캐스팅(Upcasting)이라고 합니다.
    (암시적으로 진행됩니다.)

  • 반대로 부모 클래스 타입에 담긴 자식 클래스 인스턴스를 다시 본래 타입으로 다룰 수도 있습니다. 이를 다운캐스팅(Downcasting)이라고 합니다.
    (명시적으로 진행됩니다.)

  • 업캐스팅과 다운캐스팅은 서로 상속 – 파생 관계가 아니라면 오류를 일으킬 수 있습니다.

// Magician을 Warrior타입으로 변환하고 있습니다.
// 런타임 에러이며, 프로그램이 터집니다.

  • 이런 타입 변환을 좀 더 안전하게 하고 싶다면 is연산자 와 as연산자를 사용할 수 있습니다.

is 연산자

  • 문법 : < expression > is < type >
    < expression >의 타입이 < type >과 호환될 경우 True, 아니면 False입니다.
  • as 연산자랑도 같이 사용이 가능하군요!

as 연산자

  • 문법 : < expression > as < type >
    < expression > is < type > ? (< type >)(< expression >) : (< type >)null과 같다.

  • as 연산자를 사용하지 않았을 때

  • as 연산자를 사용하면?




// characers[1]은 Magician이다. Magician은 방어력을 따로 설정하지 않았기 때문에 null값으로 빈 공간이 출력된다.

// characers[0]은 Warrior이다. Warrior에 방어력을 13으로 설정했다.

가상 멤버(Virtual Member)

  • 가상 멤버를 이용하면 자식 클래스에서 재정의(Overriding)를 할 수 있어, 업캐스팅으로 인스턴스를 다룬다고 할 때, 멤버의 사용은 같지만 실제 타입에 따라 다른 동작을 만들어낼 수 있습니다.

  • 가상 멤버는 다형성을 제공하기 위한 핵심 기능입니다.

  • 가상 멤버 앞에 virtual 한정자를 붙이며, 가상 멤버가 될 수 있는 것은
    메소드, 프로퍼티, 인덱서와 이벤트입니다. 즉, 함수인 것들만 가능합니다.

  • 재정의를 하려면 가상 함수의 반환 타잎 앞에 overrride 한정자를 붙입니다.

  • override를 사용하지 않는다면?
    재정의 되지 않아, 부모 클래스가 호출됩니다.

올바른 상속을 확일할 수 있는 방법은 'is a' 방법입니다.
Circle is a Shapes => 문맥이 맞다.
Rectangle is a Shapes => 문맥이 맞다.
Triagle is a Shapes => 문맥이 맞다.

하지만 만약 관계 없는 단어를 사용했다고 가정한다면,
Plus is a Shpaes => 문맥이 맞지 않다. 즉, 코드 재사용성에만 목적을 둔 것이라고 판단할 수 있다.
좋지 못한 코드 입니다.

타입은 정말 중요합니다.
타입을 제대로 확인하고 코드를 작성해야합니다.

sealed 멤버

  • 클래스에 sealed를 붙이면 더이상 상속할 수 없던 것처럼, 가상 멤버에 sealed를 붙여 재정의를 하면 더이상 재정의를 할 수 없게 됩니다.

추상화(Abstraction)

  • C++ 창시자 바야네 스트롭스트룹은 추상화에 대해 '구현 세부 정보를 숨기는 일반적인 인터페이스를 정의하는 행위'라고 정의했습니다.
    인터페이스에 대한 정의가 생소할 수 있으니 이에 대해 먼저 알아보겠습니다.

  • 인터페이스의 영영 사전 정의

    해석하자면 서로 다른 부분이 만나고 소통하거나 서로에게 영향을 미치는 영역을 의미합니다.

  • 실례를 들자면 선풍기를 조작한다고 할 때, 우리는 버튼을 눌러서 조작하게 되며, 선풍기가 내부적으로 어떻게 돌아가는지 잘 모릅니다. 이때 버튼을 인터페이스라고 할 수 있습니다.

  • 정리하자면 추상화를 잘 하면 잘 할 수록 데이터를 다루기 쉬워지게 되며, 이는 프로그램을 더 빠르고 편리하고 안전하게 작성할 수 있다는 것을 의미합니다.
    또한, 구현 세부 사항에 변화가 생기게 되더라도 사용하는 입장에서는 달라지는 것이 없으므로 확장성 또한 가지게 된다고 할 수 있습니다.

추상 클래스와 추상 멤버

  • abstract 한정자를 이용하면 추상화 추상 클래스를 만들거나 추상 멤버를 만들 수 있습니다.
    추상 클래스를 만들면 인스턴스를 만드는 것이 불가능해집니다.

    // 추상 타입은 불완전하기 때문에 인스턴스를 만들 수 없습니다.

  • 추상 멤버는 virtual 한정자와 마찬가지로 메소드, 인덱서, 이번트만 가능합니다.
    다만, 가상 멤버와 다르게 추상 멤버는 재정의를 강제합니다.

  • 강제하는 재정의를 하지 않는다면?

인터페이스(Interface)

  • 높은 수준의 추상화를 위해 인터페이스를 사용할 수 있습니다.

  • 인터페이스는 동작을 정의하는 용도로 사용하는 것이기 때문에 추상 클래스처럼 인스턴스를 만드는 것이 불가능하며, 모든 멤버가 추상 멤버입니다.

  • 단, 인터페이스는 다중 상속할 수 있습니다.
    인터페이스 안에 작성할 수 있는 멤버는 인스턴스 메소드, 프로퍼티, 인덱서, 이벤트와 정적 생성자, 필드, 상수, 연산자 입니다.

    • 인터페이스는 추상 클래스, 추상 멤버처럼 '강제성'을 부여해줍니다.
      그렇게함으로써 코드의 안전성을 높여줍니다.
  • 인터페이스 만들 때 규칙

  1. 이름 앞에 무조건 I를 붙여야합니다.

  2. 접근 한정자를 사용하지 않아도 됩니다.

    • 기본 한정자가 public이니까, 굳이 사용하지 않는 것입니다.
  3. 인터페이스는 '구현했다.'라고 표현합니다.

profile
고급 개발자가 되고 싶어요!

0개의 댓글