객체 지향 프로그래밍 - 클래스와 객체

dy7888·2023년 8월 10일
0

객체 지향 프로그래밍(OOP: Object-Oriented Programming)란?

C언어같은 절차 지향적인 프로그래밍이 아닌 객체의 관점에서 프로그래밍을 한다는 것이다.
기존의 절자척/구조적 프로그래밍 언어에서 가장 중요한 것은 함수였다. 인간이 기계를 이해하려는 노력에서 크게 벗어나지 못했다. 그러면서 "왜 우리가 기계 종속적인 개발을 해야하며, 우리가 보고 느끼는 주변에서 사물을 인지하는 방식으로 현실 세계처럼 프로그래밍할 수는 없을까?" 라는 고민 속에서 객체 지향의 개념이 탄생했다.

코드 재사용성이 높아지고, 유지보수 용이, 중복 코드 제거


객체 지향 프로그래밍의 4가지 특성

1. 캡슐화

캡슐화는 정보 은닉이다.
정보 은닉을 통해 객체 각각은 독립적으로 작용할 수 있도록 높은 응집도, 낮은 결합도를 유지할 수 있도록 설계한다.

쉽게 말하면, 한 곳에서 변화가 일어나도 다른 곳에서 미치는 사이드 이펙트를 최소화 시키는 것을 의미한다.
즉, 객체 내부 구조 및 데이터를 캡슐처럼 감추는 것이다.
결합도란 어떤 기능을 실행할 때 다른 클래스나 모듈에 얼마나 의존적인지를 나타낸다.

외부에서 접근할 필요 없는 것들은 private으로 접근에 제한을 두어, 외부 객체는 객체 내부의 구조를 모르게 하고, public으로 노출을 허용해 제공하는 필드와 메소드만 이용할 수 있도록 한다.
-> 의도하지 않은 동작 오류를 방지하고 유지보수 효율을 높인다.

이렇게 보호된 변수는 getter나 setter 등의 메소드를 통해서만 간접적으로 접근이 가능하다.

  • getter 외부에서 데이터를 읽어올때
  • setter 외부에서 데이터를 쓸 때

2. 상속

기존에 있던 클래스를 재사용해서, 거기에 새 기능을 추가하거나 재정의함으로써 새로운 클래스를 정의하는 것이다.

class 자식 클래스 extends 부모 클래스
  • 코드를 재사용할 수 있기 때문에 중복 코드를 방지하고 코드가 간결해진다.
  • 부모 클래스의 수정으로 모든 자식 클래스들도 수정되는 효과를 가져오기 때문에 유지 보수 시간을 최소화할 수 있다.
  • 부모 클래스의 모든 것을 물려 받는 것은 아니다.
    부모클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외된다.

    자바는 다중 상속을 지원하지 않는다.
    예를 들어, 인어 클래스가 사람과 물고기를 상속한다고 치면, 인어가 헤엄친다고 할 때 팔다리로 움직여 헤엄칠 것인지 지느러미를 이용해 헤엄칠 것인지 애매해진다. -> 다중 상속의 다이아몬드 문제
    결국 득보다 실이 더 많다 판단하여 다중 상속을 포기했지만, 실도 있다고 생각하여 대비책으로 인터페이스를 도입해 다중 상속에 대한 활로를 뚫어줬다.


3. 추상화

중요한 것은 남기고 불필요한 것은(목적과 관련이 없는 부분) 제거한다.
세상에 존재하는 모든 것을 클래스에 담고 객체를 만드는 것은 불가능하다. 그래서 추상적으로(내가 원하는 관심 영역만 추출하여 재조합) 생각해서 큰 틀의 클래스를 구현한 것이 추상클래스이다.

즉, 추상화는 모델링이다.

지구본을 생각해보자. 지구를 정확히 하나하나 다 표현할 수 있는가? 지구의 굴곡과 크기, 기후, 바다 상태를 다 표현할 수 없다.
모델은 실제 사물인 객체를 정확히 복제하는 것이 아니라 추상화를 통해 단순하게 묘사하는 것이다. 클래스는 객체들이 어떤 특징들이 있어야 한다고 정의하는 추상화된 개념이며, 추상화의 결과라고 할 수 있다.

다시 말하자면, 추상화는 객체들의 공통된 특징을 파악해 정의해 놓은 설계 기법이라고 할 수 있다.
자바의 class 키워드


4. 다형성

상속을 통해 기능 확장이나 변경을 가능하게 해준다. 같은 행위를 하지만 다양한 다른 결과를 낳을 수 있다.

다형성은 형태가 같은데 다른 기능을 하는 것이다.

예를 들어, 고양이과 클래스에 울음이라는 속성이 있다고 해보자.
사자는 고양이과이기 때문에 사자 클래스는 고양이과 클래스를 상속 받는다고 치면, 사자 클래스에도 "울음"이라는 속성이 자동 추가된다. -> 이것을 상속이라고 한다.
그런데 사자 클래스, 표범 클래스 등 고양이과마다 울음 소리가 다르게 표출되는데 이런 것을 다형성이라고 할 수 있다.

Overriding & Overloading

객체 지향 프로그래밍에서 다형성의 개념을 녹여내는 방법이 바로 오버라이딩오버로딩이다.

  • 오버라이딩(Overriding)
    상속받은 메소드를 자식 클래스에서 (새 기능을 추가하거나 재정의) 다시 수정해서 사용하는 것
    💡 접근 제한을 더 강하게 재정의할 수는 없다. (public -> private, default (X))
    💡 메소드 이름, 리턴 타입, 매개변수 목록 다 같아야 한다.
    💡 부모의 메소드에 없는 예외는 throws 할 수 없다.
  • 오버로딩(Overloading)
    클래스 내에서 같은 이름의 메소드를, 매개 변수의 타입이나 개수를 다르게 해서 여러 개 만드는 것
    💡 메소드끼리 이름은 같지만 매개변수의 개수나 타입이 달라야 오버로딩이 적용된다.
// 오버로딩이 아님, 리턴 타입은 같지만 매개변수의 개수나 타입이 같다.
int devide(int a, int b) {...}
double devide(int x, int y) {...}

✔ 메소드 오버라이딩을 하는 이유

자식 클래스가 부모 클래스의 메소드를 상속 받더라도 다른 기능을 사용하고자 하는 경우가 있기 때문!

✔ 메소드 오버로딩을 하는 이유

비슷한 기능을 하지만 다른 이름으로 메소드 이름 남발을 줄일 수 있고, 같은 기능이지만 다양한 입력값을 받을 수 있기 때문이다.

int devide(int a, int b) { ... }
double devide(double a, double b) {...}

...
devide(20, 10);
devide(20.1, 10.1);

클래스

객체를 설계하기 위한 설계도, 틀이라고 말한다.

객체

물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있으면서 식별 가능한 것을 말한다. 속성(=변수)과 동작(=메소드)으로 이루어져 있다.

클래스로부터 만들어진 객체를 해당 클래스의 인스턴스라고 한다.
클래스는 static에, 메소드는 스택 영역에, 객체는 힙 영역에 저장된다.

클래스:객체 = 붕어빵 틀:붕어빵 = 펭귄:뽀로로

객체 생성

클래스 변수 = new 클래스(); // Person person1 = new Person();


참고

profile
나의 기록하는 개발 일지

0개의 댓글