객체지향 프로그래밍
2024. 7. 17. 17:55ㆍ면접을 위한 cs 전공지식 노트/프로그래밍 패러다임
객체지향 프로그래밍(OOP)이란?
객체들의 집합으로 프로그램의 상호 작용을 표현하며 데이터를 객체로 취급하여
객체 내부에 선언된 메서드를 활용하는 방식
객체 내부에 자료형(필드)와 함수(메서드)가 같이 존재한다.
장단점
장점
- 재사용성
- 객체를 재사용할 수 있기 때문에 코드의 재사용성이 높아진다.
- 객체를 만들고 이를 사용하는 클래스에서 계속 재사용할 수 있다.
- 코드의 가독성
- 클래스와 객체를 이용하면 함수와 변수 등을 그룹화하여 구조화할 수 있어 코드를 쉽게 이해하고 디버깅할 수 있다.
- 유지보수성
- 객체지향 프로그래밍은 변경이 필요한 경우 해당 객체만 수정하면 되므로 유지보수가 쉽다.
- 캡슐화, 상속, 다형성 등의 객체지향 특징을 통해 프로그램을 더 효울적으로 개발할 수 있다.
단점
- 처리 속도
- 객체 간 메시지 전달, 객체 생성 등의 처리가 필요하여 절차지향 언어에 비해 처리속도가 느릴 수 있다.
- 설계의 어려움
- 객체지향 프로그래밍은 설계 단계에서 상당한 시간과 노력이 필요하며, 설계를 잘못하면 프로그램 전체에 문제가 생길 수 있다.
- 메모리 사용량
- 클래스의 인스턴스를 만들 때마다 메모리를 사용하므로, 메모리 사용량이 크다는 단점이 있다.
특징
- 추상화 - 필요로 하는 속성이나 행동을 추출하는 작업
- 추상화란?
- 세부적인 사물들의 공통적인 특징을 파악한 후 하나의 집합으로 만들어 내는 것.
ex) 현대, 기아 아우디, BMW - 자동차
- 세부적인 사물들의 공통적인 특징을 파악한 후 하나의 집합으로 만들어 내는 것.
- 왜?
- 추상화로 구현해두면 다른곳의 코드는 수정할 필요 없이 추가로 만들 부분만 새로 생성 - 유연성
- 추상화란?
- 캡슐화 - 낮은 결합도를 유지할 수 있도록 설계하는 것
- 캡슐화란?
- 객체가 내부적으로 기능을 어떻게 구현하는지 감추는 것.
- 자바에서는 private 같은 접근제어자를 사용하여 정보를 은닉
- 왜?
- 외부 접근을 제어함으로써 높은 응집도와 낮은 결합도를 갖게함
-> 한 곳에서 변화가 일어나도 다른 곳에 미치는 영향을 최소화 시킴
- 외부 접근을 제어함으로써 높은 응집도와 낮은 결합도를 갖게함
- 캡슐화란?
- 상속 - 여러 개체들이 지닌 공통된 특성을 부각시켜 하나의 개념이나 법칙으로 성립하는 과정
- 상속이란?
- 한 클래스가 다른 클래스의 속성과 메서드를 물려받는 것
- 자식 클래스를 외부로부터 은닉하는 캡슐화의 일종
- 왜?
- 재사용성
- 이미 잘 작동하는 클래스의 코드를 새로운 클래스에서 재사용할 수 있다.
이를 통해 중복 코드를 줄이고 코드의 관리를 효율적으로 할 수 있다.
- 이미 잘 작동하는 클래스의 코드를 새로운 클래스에서 재사용할 수 있다.
- 확장성
- 기존 클래스를 상속받아 새로운 기능을 추가하거나 기존 기능을 수정함으로써 새로운 클래스를 생성할 수 있다.
- 유지보수성
- 코드의 수정이 필요할 때, 상위 클래스의 코드만 수정하면 해당 클래스를 상속받은 모든 하위 클래스에서도 그 변경사항이 반영된다.
- 재사용성
- 상속 재사용의 단점
- 상위 클래스(부모 클래스)의 변경이 어려워진다.
- 부모 클래스에 의존하는 자식 클래스가 많을 때, 부모 클래스의 변경이 필요하다면?
-> 이를 의존하는 자식 클래스들이 영향을 받게 된다. - 불필요한 클래스가 증가할 수 있다.
- 유사기능 확장시, 필요 이상의 불필요한 클래스를 만들어야 하는 상황이 발생할 수 있다.
- 상속이 잘못 사용될 수 있다.
- 같은 종류가 아닌 클래스의 구현을 재사용하기 위해 상속을 받게 되면, 문제가 발생할 수 있다.
상속받는 클래스가 부모 클래스와 is-A 관계가 아닐 때 이에 해당한다.
(is-A관계란 특정 클래스가 다른 클래스의 '하위 형태'임을 나타내는 것)
- 같은 종류가 아닌 클래스의 구현을 재사용하기 위해 상속을 받게 되면, 문제가 발생할 수 있다.
- 부모 클래스에 의존하는 자식 클래스가 많을 때, 부모 클래스의 변경이 필요하다면?
- 상위 클래스(부모 클래스)의 변경이 어려워진다.
- 상속이란?
- 다형성 - 서로 다른 클래스의 객체가 같은 메시지를 받았을 때의 각자의 방식으로 동작하는 능력
- 다형성이란?
- 같은 이름의 메서드가 다른 동작을 수행하는 것을 의미
- 왜?
- 코드의 유연성
- 다형성을 활용하면 같은 이름의 메서드가 다양한 클래스에 적용될수 있으므로 코드의 유연성이 증가한다.
- 메서드의 이름만 알면 어떤 객체에서든 해당 메서드를 사용할 수 있게 된다.
- 확장성과 유지보수성
- 만약 새로운 클래스를 추가하더라도 기존의 코드를 변경할 필요 없이 새로운 클래스에서 메서드를 재정의하면 된다.
- 코드의 재사용
- 상위 클래스의 메서드를 하위 클래스에서 재정의하여 사용한다.
- OverLoading
- OverLoading이란?
- 같은 이름을 가진 메서드를 여러 개 두는 것 - 메서드의 타입, 매개변수의 유형, 개수 등으로 구분
- 컴파일 중에 발생하는 정적 다형성
- OverLoading이란?
- OverRiding
- OverRiding이란?
- 주로 메서드 오버라이딩을 말하며 상위 클래스로부터 상속받은 메서드를 하위 클래스가 재정의하는 것
- 런타임 중에 발생하는 동적 다형성
- OverRiding이란?
- OverLoading
- 상위 클래스의 메서드를 하위 클래스에서 재정의하여 사용한다.
- 코드의 유연성
- 다형성이란?
OverLoading 예시
class Person {
public void eat(String a) {
System.out.println("I eat " + a);
}
public void eat(String a, String b) {
System.out.println("I eat " + a + " and " + b);
}
}
public class CalculateArea {
public static void main(String[] args) {
Person a = new Person();
a.eat("apple");
a.eat("tomato", "phodo");
}
}
/*
I eat apple
I eat tomato and phodo
*/
OverRiding 예시
class Animal {
public void bark() {
System.out.println("mumu! mumu!");
}
}
class Dog extends Animal {
@Override
public void bark() {
System.out.println("wal!!! wal!!!");
}
}
public class Main {
public static void main(String[] args) {
Dog d = new Dog();
d.bark();
}
}
/*
wal!!! wal!!!
*/
객체 지향 설계 과정
- 제공해야 할 기능을 찾고 세분화한다. 그리고 그 기능을 알맞은 객체에 할당한다.
- 기능을 구현하는데 필요한 데이터를 객체에 추가한다.
- 그 데이터를 이용하는 기능을 넣는다.
- 기능은 최대한 캡슐화하여 구현한다.
- 객체 간에 어떻게 메소드 요청을 주고받을지 결정한다.
객체 지향 설계 원칙
SOLID라고 부르는 5가지 설계 원칙이 존재한다.
- SRP(Single Responsibility) - 단일 책임 원칙
- 클래스는 단 한개의 책임을 가져야 한다.
- 클래스를 변경하는 이유는 단 한개여야 한다.
- 이를 지키지 않으면, 한 책임의 변경에 의해 다른 책임과 관련된 코드에 영향이 갈 수 있다.
- OCP(Open - Closed) - 개방 - 폐쇄 원칙
- 확장에는 열려있어야 하고, 변경에는 닫혀 있어야 한다.
- 기능을 변경하거나 확장할 수 있으면서, 그 기능을 사용하는 코드는 수정하지 않는다.
- 이를 지키지 않으면, instanceOf와 같은 연산자를 사용한거나 다운 캐스팅이 일어난다.
- LSP(Liskov Substitution) - 리스코프 치환 원칙
- 상위 타입의 객체를 하위 타입의 객체로 치환해도, 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
- 상속 관계가 아닌 클래스들을 상속 관계로 설정하면 이 원칙이 위배된다.
- ISP(Interface Segregation) - 인터페이스 분리 원칙
- 인터페이스는 그 인터페이스를 사용하는 클라이언트 기준으로 분리해야 한다.
- 각 클라이언트가 필요로 하는 인터페이스들을 분리함으로써, 각 클라이언트가 사용하지 않는 인터페이스에 변경이 발생하더라도 영향을 받지 않도록 만들어야한다.
- DIP(Dependency Inversion) - 의존 역전 원칙
- 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다.
- 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야 한다.
- 즉, 저수준 모듈이 변경돼도 고수준 모듈은 변경할 필요가 없다.
'면접을 위한 cs 전공지식 노트 > 프로그래밍 패러다임' 카테고리의 다른 글
선언형과 함수형 프로그래밍 (0) | 2024.07.15 |
---|