OOP (객체 지향 프로그래밍)의 특징 정리

onady·2022년 4월 16일
0

OOP란?

객체의 관점에서 프로그래밍을 한다는 것으로 객체를 기준으로 코드를 나누어 구현하는 설계 방법론이다.
객체들의 유기적인 관계를 통해서 프로세스가 진행된다. 즉, 애플리케이션을 구성하는 요소들을 객체로 바라보고, 객체들을 유기적으로 연결하여 프로그래밍 하는 것을 말한다.
객체들이 공통적으로 갖는 속성들을 모아서 정의내린 것을 클래스라고 한다. (이를 추상화라고 하는데 뒤에서 살펴보자)

OOP 특징

1. 캡슐화(Encapsulation)

하나의 객체에 대해 그 객체가 특정한 목적을 위해 필요한 변수나 메소드를 하나로 묶는 것을 의미한다.

어떠한 클래스를 사용할 때 내부 동작이 어떻게 돌아가는지 모르더라도 사용법만 알면 쓸 수 있도록 클래스 내부를 감추는 기법이다.

클래스 내에서 사용되는 변수나 메서드를 원하는 대로 감출 수 있기 때문에 필요 이상의 변수나 메서드가 클래스 외부로 노출되는 것을 방어하여 보안도 챙길 수 있다.

예를들어. 리모콘을 사용하는데 내부 회로를 알 필요가 없다.

이렇게 클래스 내부의 데이터를 감추는 것을 정보 은닉(Information Hiding)이라고 하며, 보통 public, private, protected 같은 접근제한자를 사용하여 원하는 정보를 감추거나 노출시킬 수 있다.

2. 추상화(Abstraction)

객체들의 공통된 특징을 파악해 정의해 놓은 설계 기법이라고 할 수 있다.

예를들어. 리트리버, 보스턴테리어, 말티즈 등 우리가 생각하는 여러 종류의 강아지를 모두 포괄하는 강아지라는 단어를 생각해보자(즉, 확장성 때문에 추상화 할 필요가 있다.)

방금 나열한 강아지들의 공통적인 요소나 특징을 추출하는 과정인 추상화를 거쳐 요소를 끄집어 내면 눈, 코, 입, 털 등 필수적인 부품이 있다.

울음, 달리기 등 공통적인 행동 즉 어떤 강아지든 필수적으로 필요한 메서드가 추출된다.

이러한 과정이 추상화 하는 과정이다.

클래스는 어떤 특징들이 있어야 한다고 정의하는 추상화된 개념이다.

3. 상속성, 재사용(Ingeritance)

상속이란 기존 상위클래스에 근거하여 새롭게 클래스 와 행위를 정의할 수 있게 도와주는 개념이다.

기존 클래스에 기능을 가져와 재 사용할 수 있으면서도 동시에 새로운 기능을 추가할 수 있다.

실제 세계에서 부모로부터 여러 가지를 상속 받는데, OOP 에서 도 가능하다. OOP 에서 이를 부모 클래스, 자식 클래스 라고 표현한다.

예를 들어, 고양이 클래스 와 강아지 클래스가 있다고 했을 때, 고양이와 강아지는 모두 포유류에 해당한다.
포유류는 여러 속성들이 정의되어 있는데 고양이와 강아지는 포유류의 이런 속성들을 갖고 있다.
즉, 포유류 라는 클래스는 고양이와 강아지 클래스에 속성들을 물려준다. 이것을 상속이라고 한다.

상속이 필요한 이유

코드의 중복을 없애기 위함이다.
(코드의 중복이 많아지면 개발 단계에서도 피곤하지만, 유지 보수에서도 많은 비용이 들게 된다.)

포유류 클래스에 여러 속성들을 정의 해놓고 포유류에 해당하는 종, 예를 들면 강아지 클래스가 필요한 경우 포유류 클래스 와 상속 관계를 맺는다. 상속 관계를 맺으면 자식 객체를 생성할 때 부모 클래스의 속성들을 자동으로 물려받기 때문에 자식 클래스에서 또 정의할 필요가 없다.
(속성 재 정의가 필요 한 상황도 있는데 아래 다형성 에서 확인하자)

4. 다형성(Polymorphism)

다형성은 상속을 통해 기능을 확장하거나 변경하는 것을 가능하게 해준다. 즉, 다형성은 형태가 같은데 다른 기능을 하는 것을 의미한다.(같은 동작이지만 다른 결과물이 나올 때 다형이라고 생각하면 된다.)
이를 통해 코드의 재사용, 코드 길이 감소로 유지보수가 용이하도록 도와준다.

예를 들어 포유류 클래스에 울음라는 속성이 정의되어 있다고 하면,
강아지 클래스와 고양이 클래스가 포유류 클래스를 상속받을 경우 강아지 클래스와 고양이 클래스에도 울음 속성이 자동으로 추가된다.

그런데 강아지와 고양이의 울음 소리는 다르다.
이런것을 다형성이라고 말할 수 있다.

다형성의 장점

같은 이름의 속성을 유지함으로서, 속성을 사용하기 위한 인터페이스를 유지하고, 메서드 이름을 낭비하지 않는다는 것이다.

예를 들어, 고양이와 사자의 울음소리를 호출하기 위해서 각 객체에서 roar() 메서드를 호출하면 된다.
roraCat(), roarLion()으로 각각을 정의할 필요가 없다는 것이다.
API가 많아질수록 복잡성은 증가하기 때문에 다형성은 유용하다.

Overriding & Overloading

OOP에서 다형성의 개념을 녹여내는 방법은 두가지 인데, 바로 오버라이딩(Overriding)과 오버로딩(Overloading)이다.

  • 오버라이딩
    • 부모 클래스에서 만들어진 메서드를 자식 클래스에서 자신의 입맛대로 다시 재정의해서 사용하는 것을 말한다.
  • 오버로딩
    • 같은 이름의 메서드를 사용하지만 메서드마다 다른 용도로 사용되며 그 결과물도 다르게 구현할 수 있게 만드는 개념
    • 같은 이름의 메서드에 매개변수의 갯수나 데이터 타입이 다르면 오버로딩이 적용된다.
public class Mammalia{
  
  public String name;
  public int age;
  
  public void crying(){
    System.out.println("포유류의 울음소리");
  }
}

//Emplyee 상속
public class Dog extends Mammalia{
  
  // overriding  
	// Mammalia의 crying() 메소드 오버라이딩
  public void crying(){
    System.out.println("강아지의 울음소리");
  }
}

//Overloading
public class Overloading{
  
  public void test(){
    System.out.println("출력 내용");
  }
  
  public void test(String data){
    System.out.println("출력 내용 다르게" + data);
  }
  
  public void test(int data){
    System.out.println("출력 내용 또 다르게" + data);
  }
}

참조

0개의 댓글