👨‍💻객체지향 프로그래밍이란?


객체지향 프로그래밍은 프로그램의 규모가 점점 커지고 빠르게 바뀌면서 절차적 or 구조적 or 함수형 프로그래밍의 한계를 느끼고 개선한 프로그래밍 패러다임 중 하나로 실제 세계는 사물(객체)로 이루어져 있고, 발생하는 모든 사건들을 사물(Object)들 간의 상호작용하는 것이라는 기본 개념을 가지고 실제 세계를 모델링(객체화)하여 프로그래밍 하는 방식이다.

객체 지향 프로그래밍 바로 이전에는 많은 코드들이 함수형 프로그래밍으로 작성되었다.
하지만 코드량이 많아질수록 어떤 함수가 다른 함수를 변경하고, 다른 함수들을 깨지게 하는 것이 발생할 확률이 높아졌다.
이러한 코드들을 스파게티코드라고 부르는데, 함수형 프로그래밍은 상호의존성(interdependency)이 매우 크기 때문에 위같은 문제가 발생할 수 있기 때문에 이를 보완하고자 객체지향 프로그래밍이 등장하게 되었다.

객체지향 프로그래밍은 간단하게 말해서 기능별로 연관된 변수와 함수를 묶어 하나의 그룹단위를 만드는 것을 말하는데 이러한 단위를 객체라고 부르는 것이다.

🔵 객체지향 프로그래밍의 장점

  1. 코드의 재사용성이 높다. (기존 코드를 이용하여 중복을 줄일 수 있다.)
  2. 코드를 유지보수 및 관리하기 용이하다.
  3. 디버깅이 쉽다.

🔴 객체지향 프로그래밍의 단점

  1. 절차지향보다 속도가 느리다.
  2. 설계에 필요한 시간이 늘어난다.


👨‍💻절차지향 프로그래밍이란?


프로그래밍을 위에서 아래로 순차적으로 처리하는 프로그래밍 방법으로. 코드를 유기적으로 연결하여 순서대로 작성하는 프로그래밍 패러다임이고, 대표적인 절차지향적 프로그래밍 언어에는 C언어가 있다.

🔵 절차지향 프로그래밍의 장점

  1. 컴퓨터 처리구조와 유사하여 실행속도가 빠르다.

🔴 절차지향 프로그래밍의 단점

  1. 코드의 수정 및 유지보수가 어렵다.
  2. 모든 코드가 유기적으로 연결되어 있어 오류 발생시 전체 시스템이 고장날 수 있다.
  3. 코드의 순서가 바뀌면 동일한 결과를 보장하기 어렵다.
  4. 디버깅이 어렵다.


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


이러한 객체지향 프로그래밍에는 4가지의 특성(기둥)이 자리하고 있다.
캡슐화, 추상화, 상속, 다형성이 객체지향 프로그래밍의 4가지 주된 특성이라고 할 수 있다.

캡슐화(Encapsulation)

기능별로 연관된 속성(Property)과 메서드(Method)를 객체에 묶는 특성

public class Dog {
	String name;
    
    public Dog(String name) {
    	this.name = name;
    }
    
    public void bark() {
    	System.out.println("멍 멍");
    }
}

위처럼 개와 관련된 속성(Property)과 메서드(Method)를 하나의 묶음(Class)로 만드는 것을 캡슐화라고 한다.

추상화(Abstraction)

비슷한 개념이나 의미를 가진 것들을 묶어 간단하게 표현할 수 있는 특성
추상화된 메서드를 통해 내부적으로 어떻게 구현되어있는지 알 수 없지만 실행 결과를 추상적으로 알 수 있는 특성

	ArrayList list = new ArrayList();
    System.out.println(list.size());

자바의 ArrayList를 사용할 때
위 코드를 보면, ArrayList의 size라는 메서드가 어떻게 구현되어있는지 알지 못하지만
우리는 저 메서드가 리스트의 크기를 반환하는 함수라는 것 추상적으로 알 수 있다.

상속(Inheritance)

공통이 되는 속성이나 메서드들을 상속을 통해 중복을 방지하여 불필요한 코드 작성을 줄이는 특성

class Animal {
	String name;
}

class Dog extends Animal{
}

class Cat extends Animal{
}

예를들어 Dog 클래스에도 name이라는 속성이 있고 Cat 클래스에도 name이라는 속성이 있다면
이 공통되는 특성을 가진 Animal 클래스를 만들어 Dog과 Cat 클래스가 Animal 클래스를 상속하게 한다.

다형성(Polymorphism)

Poly(많다) + Morphism(형태)라는 뜻으로 하나의 메서드가 다양한 형태를 가지고 있을 수 있다는 특성

// 강아지
public class Dog {
	public void bark() {
    	System.out.println("멍멍");
    }
}

// 고양이
public class Cat {
	public void bark() {
    	System.out.println("야옹");
    }
}

예를들어 Dog 클래스도 우는 메서드가 있고 Cat 클래스도 우는 메서드가 있다면
이 공통되는 "울다"라는 기능을 가진 메서드가 "멍멍"과 "야옹" 두가지의 형태가 될 수 있다는 것이다.

정리

객체지향 프로그래밍은 기능별로 연관된 속성(변수)와 메서드(함수)를 묶어서 - 캡슐화
내부에 구현을 숨기고 어떻게 실행되는지만 알 수 있게하고 - 추상화
공통되는 속성이나 메서드 등은 상속을 통해 중복을 제거하고 - 상속
같은 메서드가 다양한 형태를 가질 수 있게 한다. - 다형성


👨‍💻객체지향 프로그래밍의 5대 원칙(SOLID)

'Clean Code'의 저자 로버트 마틴이 객체지향 프로그래밍의 5대 기본 원칙을 제시하고
이를 마이클 패더스가 SOLID라는 약어를 통해서 객체지향 프로그래밍의 5대 원칙을 한단어로 축약해 제시하였다.

S (SRP: Single Responsibility Principle)

단일 책임 원칙으로 한 클래스하나의 책임만을 가져아 한다는 의미이다.

O (OCP: Open Closed Principle)

개방 폐쇠 원칙으로 확장에는 열려있고(Open), 변경에는 닫혀있다(Closed)는 의미이다.

L (LSP: Liskov's Substitution Principle)

리스코프 치환 원칙으로 부모 객체를 상속받은 자식 객체는 항상 부모 타입으로 치환할 수 있어야 한다는 의미이다.

자바에서는 Upcasting과 Downcasting이라는 개념이 존재한다.
Upcasting: 자식객체를 부모타입의 객체로 치환하는 것 (타입 캐스팅이 자동으로 일어난다.)

Person p = new Student();

Downcasting: 부모객체를 자식타입의 객체로 치환하는 것 (타입 캐스팅을 직접 실시해야 하며, 오류가 발생할 수 있다.)

Student s = (Person) new Person();

위 예시에서 자식 객체가 부모 타입으로 치환되는 경우는 바로 Upcasting이다.
Person을 상속받은 Student는 항상 Person 타입으로 치환이 가능해야 하며
자바에서는 이때 타입 캐스팅을 자동적으로 지원해주는 것을 보았을 때
객체지향의 5대원칙인 LSP를 잘 실천하고 있는 것이다.

I (ISP: Interface Segregation Principle)

인터페이스 분리 원칙으로 객체를 구현할 때, 무의미한(객체가 사용하지 않는) 메서드를 구현하지 않고
반드시 필요한 메서드만을 상속 및 구현하도록 하며
각각의 독립된 기능을 인터페이스로 분리하여 서로에게 영향받지 않게 설계해야 한다는 의미이다.

예를들어, A B C D라는 기능을 가진 코드들이 한 클래스에 모두 작성되어 있다.
1번 사람은 A와 C기능이 필요하고
2번 사람은 B와 C기능이 필요하다면,
D 기능은 필요하지 않기 때문에 ISP에 의해 구현하지 않는게 맞다.
또한, 1번 사람이 A와 C 기능을 필요로 한다고 ABCD기능을 모두 가진 하나의 클래스를 상속해버린다면,
불필요한 코드(BD기능)를 갖게 되므로, ISP에 어긋나게 된다.

D (DIP: Dependency Inversion Principle)

의존성 역전 법칙으로 하위(저수준)의 객체들이 상위(고수준)에 의존해야 한다는 원칙이다.

여기서, 하위(저수준) 객체라는 것은 자식 클래스 등의 실제로 구현된 객체를 의미하고
상위(고수준) 객체라는 것은 인터페이스, 부모 클래스 등의 추상적인 틀을 의미한다.

profile
백엔드를 사랑하는 초보 개발자

0개의 댓글