객체지향 프로그래밍(OOP)이란?
객체지향 프로그래밍이란 객체들의 집합으로 프로그램의 상호 작용을 표현하며 데이터를 객체로 취급하여
객체 내부에 선언된 메서드를 활용하는 방식. 객체 내부에 자료형(필드)와 함수(메서드)가 같이 존재
장단점
•
장점
◦
재사용성 : 객체를 재사용할 수 있기 때문에 코드의 재사용성이 높아집니다. 객체를 만들고 이를 사용하는 클래스에서 계속 재사용할 수 있습니다.
◦
코드의 가독성 : 클래스와 객체를 이용하면 함수와 변수 등을 그룹화하여 구조화할 수 있어, 코드를 쉽게 이해하고 디버그할 수 있습니다.
◦
유지 보수성 : 객체지향 프로그래밍은 변경이 필요한 경우 해당 객체만 수정하면 되므로 유지 보수가 쉽습니다. 캡슐화, 상속, 다형성 등의 객체지향 특징을 통해 프로그램을 더 효율적으로 개발할 수 있습니다.
•
단점
◦
처리 속도: 객체 간 메시지 전달, 객체 생성 등의 처리가 필요하여 절차지향 언어에 비해 처리 속도가
느릴 수 있습니다.
◦
설계의 어려움: 객체지향 프로그래밍은 설계 단계에서 상당한 시간과 노력이 필요하며, 설계를 잘못하면 프로그램 전체에 문제가 생길 수 있습니다.
◦
메모리 사용량: 클래스의 인스턴스를 만들 때마다 메모리를 사용하므로, 메모리 사용량이 크다는
단점이 있습니다.
특징
•
추상화 - 필요로 하는 속성이나 행동을 추출하는 작업
◦
추상화란?
▪
세부적인 사물들의 공통적인 특징을 파악한 후 하나의 집합으로 만들어 내는 것.
ex) 현대, 기아, 아우디, BMW → 자동차
◦
왜?
▪
추상화로 구현해두면 다른곳의 코드는 수정할 필요 없이 추가로 만들 부분만 새로 생성 → 유연성
•
캡슐화 - 낮은 결합도를 유지할 수 있도록 설계하는 것
◦
캡슐화란?
▪
객체가 내부적으로 기능을 어떻게 구현하는지 감추는 것.
▪
자바에서는 private 같은 접근제어자 사용하여 정보를 은닉
◦
왜?
▪
외부 접근을 제어함으로써 높은 응집도와 낮은 결합도를 갖게함
→ 한 곳에서 변화가 일어나도 다른 곳에 미치는 영향을 최소화 시킴
추상화와 상속의 차이점
•
상속 - 여러 개체들이 지닌 공통된 특성을 부각시켜 하나의 개념이나 법칙으로 성립하는 과정
◦
상속이란?
▪
한 클래스가 다른 클래스의 속성과 메서드를 물려받는 것
▪
자식 클래스를 외부로부터 은닉하는 캡슐화의 일종
◦
왜?
▪
재사용성 : 이미 잘 작동하는 클래스의 코드를 새로운 클래스에서 재사용할 수 있습니다.
이를 통해 중복 코드를 줄이고 코드의 관리를 효율적으로 할 수 있습니다.
▪
확장성 : 기존 클래스를 상속받아 새로운 기능을 추가하거나 기존 기능을 수정함으로써 새로운
클래스를 생성할 수 있습니다. 이를 통해 프로그램의 확장성이 향상됩니다.
▪
유지 보수성 : 코드의 수정이 필요할 때, 상위 클래스의 코드만 수정하면 해당 클래스를 상속받은
모든 하위 클래스에서도 그 변경 사항이 반영됩니다. 이를 통해 유지 보수의 효율성이 향상됩니다.
◦
상속 재사용의 단점
1.
상위 클래스(부모 클래스)의 변경이 어려워진다.
a.
부모 클래스에 의존하는 자식 클래스가 많을 때, 부모 클래스의 변경이 필요하다면?
이를 의존하는 자식 클래스들이 영향을 받게 된다.
2.
불필요한 클래스가 증가할 수 있다.
a.
유사기능 확장시, 필요 이상의 불필요한 클래스를 만들어야 하는 상황이 발생할 수 있다.
3.
상속이 잘못 사용될 수 있다.
a.
같은 종류가 아닌 클래스의 구현을 재사용하기 위해 상속을 받게 되면, 문제가 발생할 수 있다. 상속 받는 클래스가 부모 클래스와 IS-A 관계가 아닐 때 이에 해당한다.
(IS-A관계란 특정 클래스가 다른 클래스의 '하위 형태'임을 나타내는 것)
•
다형성 - 서로 다른 클래스의 객체가 같은 메시지를 받았을 때의 각자의 방식으로 동작하는 능력
◦
다형성이란?
▪
같은 이름의 메서드가 다른 동작을 수행하는 것을 의미
◦
왜?
1.
코드의 유연성: 다형성을 활용하면, 같은 이름의 메서드가 다양한 클래스에 적용될 수 있으므로 코드의 유연성이 증가합니다. 즉, 메서드의 이름만 알면 어떤 객체에서든 해당 메서드를 사용할 수 있게 됩니다.
2.
확장성과 유지보수성: 다형성은 프로그램의 확장성과 유지 보수성을 향상시킵니다. 만약 새로운 클래스를 추가하더라도 기존의 코드를 변경할 필요 없이 새로운 클래스에서 메서드를 재정의하면 됩니다.
3.
코드의 재사용: 상위 클래스의 메서드를 하위 클래스에서 재정의하여 사용하므로 코드의 재사용성이 높아집니다.
◦
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
*/
Java
복사
◦
OverRiding
▪
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!!!
*/
Java
복사
객체 지향 설계 과정
•
제공해야 할 기능을 찾고 세분화한다. 그리고 그 기능을 알맞은 객체에 할당한다.
•
기능을 구현하는데 필요한 데이터를 객체에 추가한다.
•
그 데이터를 이용하는 기능을 넣는다.
•
기능은 최대한 캡슐화하여 구현한다.
•
객체 간에 어떻게 메소드 요청을 주고받을 지 결정한다.
객체 지향 설계 원칙
SOLID라고 부르는 5가지 설계 원칙이 존재한다.
1.
SRP(Single Responsibility) - 단일 책임 원칙
클래스는 단 한 개의 책임을 가져야 한다.
클래스를 변경하는 이유는 단 한개여야 한다.
이를 지키지 않으면, 한 책임의 변경에 의해 다른 책임과 관련된 코드에 영향이 갈 수 있다.
2.
OCP(Open-Closed) - 개방-폐쇄 원칙
확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다.
기능을 변경하거나 확장할 수 있으면서, 그 기능을 사용하는 코드는 수정하지 않는다.
이를 지키지 않으면, instanceof와 같은 연산자를 사용하거나 다운 캐스팅이 일어난다.
3.
LSP(Liskov Substitution) - 리스코프 치환 원칙
상위 타입의 객체를 하위 타입의 객체로 치환해도, 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
상속 관계가 아닌 클래스들을 상속 관계로 설정하면, 이 원칙이 위배된다.
4.
ISP(Interface Segregation) - 인터페이스 분리 원칙
인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다.
각 클라이언트가 필요로 하는 인터페이스들을 분리함으로써, 각 클라이언트가 사용하지 않는 인터페이스에 변경이 발생하더라도 영향을 받지 않도록 만들어야 한다.
5.
DIP(Dependency Inversion) - 의존 역전 원칙
고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다.
저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야 한다.
즉, 저수준 모듈이 변경돼도 고수준 모듈은 변경할 필요가 없는 것이다.