개발 기록
>[Java] Java 객체지향 프로그래밍(OOP, Object-Oriented Programming)에 대하여 본문

Java는 객체지향 프로그래밍 언어이다. 객체는 뭐고 그런 객체를 지향한다는 건 어떤 뜻을 가지고 있는 걸까?
■
1. 개념
▶ 객체 - Object
물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 다른 것과 식별 가능한 것
ex.
- 물리적 성격: 자동차, 자전거, 책, 사람 등
- 추상적 성격의 학과, 강의, 주문 등
▶ 객체 모델링
현실 세계 객체의 속성과 동작을 추려내어 소프트웨서 객체의 필드와 메소드로 정의하는 과정이라고 볼 수 있다.
예를 들어 사람은 이름, 나이 등의 속성이 있고 동작으로는 웃다, 걷다 등이 있다.
자바는 이 속성과 동작들을 각가 필드와 메소드라고 부른다.

▶ 객체지향적 프로그래밍
다양한 개념과 원칙을 포함하여 프로그램을 설계하고 구현하는 방법론으로 여러 가지 요소들이 조합되어 객체지향 프로그래밍을 구성한다.
① 객체 조립: 부품 객체들을 조합하여 기능 구현 (* 부품 객체:특정 기능이나 역할을 수행하는 작은 단위)
② 객체 모델링
③ 객체 간의 관계 모델링:
- 집합 관계 : 햄버거(완성품 객체) = 패티(부품 객체)+상추(부품 객체)+치즈(부품 객체)
- 사용 관계 : 손님(객체A)은 롯데리아 (객체B) 키오스크 (객체B의 메서드)를 사용하여 햄버거 를 주문한다.
④ 객체간의 상호작용: 나(객체)는 햄버거(객체)를 구입했다(행위 실체화).
⑤ 주요 개념: 캡슐화, 상속, 다형성, 추상화
⑥ 주요 원칙: 단일 책임 원칙, 개방 폐쇄 원칙, 리스코프 치환 원칙, 인터페이스 분리 원칙, 의존성 역전 원칙
■
2. 객체와 클래스
객체는 하늘에서 뚝 떨어지는게 아니다! 햄버거가 하늘에서 갑자기 뚝 떨어지는게 아니라 레시피를 바탕으로 만들어지듯 말이다.
자바에서 이 레시피가 바로 클래스이다. 클래스에는 필드(객체의 속성)와 메소드(행위)가 정의되어 있고 클래스로부터 만들어진 객체를 '인스턴스' 라고한다.
정리하자면
☞ 클래스(Class): 객체를 생성하기 위한 틀 또는 설계도
☞ 객체(Object): 클래스를 기반으로 생성된 구체적인 데이터를 가지고 있는 개체
☞ 인스턴스(Instance): 클래스로부터 생성된 객체로 실제로 메모리에 할당되어 실행되는 상태
* "객체"와 "인스턴스" 모두 클래스를 기반으로 생성된 것을 가리키지만, "객체"는 보다 일반적인 용어로서 클래스의 인스턴스를 의미하고, "인스턴스"는 구체적으로 클래스로부터 생성된 특정 객체를 가리킨다.
(1) 클래스 선언
@Data
@Allargsconstructor
@Noargsconstructor
public class Burger {
private String type; // 햄버거 종류
private String pattyType; // 패티 종류
private boolean hasLettuce; // 상추 포함 여부
private boolean hasCheese; // 치즈 포함 여부
// 햄버거 주문 메서드
public void orderBurger() {
System.out.println("주문하신 " + type + " 햄버거가 제조되었습니다!");
}
// 추가적인 햄버거 설정 메서드
public void addLettuce() {
this.hasLettuce = true;
System.out.println("상추가 추가되었습니다.");
}
public void addCheese() {
this.hasCheese = true;
System.out.println("치즈가 추가되었습니다.");
}
(2) 객체생성
★ 'new' 연산자를 사용하여 클래스로부터 객체를 생성시킨다.
★ 'new' 연산자로 생성된 객체는 메모리 힙(heap) 영역에 생성된다.
★ 'new' 연산자는 힙 영역에 객체를 생성하고 객체의 주소를 리턴한다.
★ 리턴된 객체의 주소에 저장하면 아래와 같이 변수가 객체를 참조하게 되고, 변수를 통해 객체를 사용할 수 있다.

public class Main {
public static void main(String[] args) {
// 햄버거 객체 생성
// 클래스 변수 = new 클래스();
Burger burger = new Burger("치즈버거", "소고기 패티", true, true);
}
}
■
3. 객체지향 프로그래밍 특징
(1) 캡슐화(Encapsulation)
객체의 상태(데이터)와 행위(메서드)를 하나로 묶고, 외부의 접근을 제어하여 객체 내부의 상태를 보호하는 개념이다.
- public: 외부 접근을 제한 하지 않는다. 다른 클래스 어디에서든 접근 가능
- private: 해당 클래스 내부에서만 접근 허용
- protected: 같은 패키지, 상속 받은 하위 클래스 에서만 접근 가능
- default(packeage-private): 별도의 접근 제어자를 명시하지 않은 경우 기본 접근 수준, 같은 패키지 내에서만 접근 가능
public class Student {
// 이 변수들은 getName()과 getAge() 메서드를 통해 간접적으로 접근할 수 있다.
private String name;
private int age;
// 생성자, Getter 메서드
.....
}
(2) 상속(Inheritance)
상속은 기존 클래스(부모 클래스)의 특성과 기능을 그대로 물려받아 새로운 클래스(자식 클래스)를 생성하는 개념이다. 상속을 통해 코드의 재사용성을 높이고 클래스 간의 계층 구조를 구축할 수 있다.
// 상속 예제: Animal 클래스와 Dog 클래스
public class Animal {
public void eat() {
System.out.println("동물이 먹는다.");
}
}
// Animal 클래스를 상속받는 Dog 클래스
public class Dog extends Animal {
public void bark() {
System.out.println("멍멍!");
}
}
(3) 다형성(Polymorphism)
다형성은 같은 이름의 메서드나 연산자('+')가 여러 형태로 동작할 수 있는 특성을 의미한다.
1. 메서드 다형성
- 오버로딩(Overloading): 같은 이름의 메서드가 매개변수의 타입, 개수, 순서가 다르게 정의되는 것
- 오버라이딩(Overriding): 하위 클래스에서 상위 클래스 메서드 재정의하여 사용
2. 객체 다형성: 상위 클래스 타입으로 선언된 변수는 해당 상위 클래스 또는 하위 클래스의 인스턴스를 참조
3. 연산자 다형성: + 연산자는 정수형 변수 간에는 덧셈을 수행하지만, 문자열(String)과 문자열 간에는 문자열 연결을 수행
public class Main {
public static void main(String[] args) {
Animal animal = new Dog(); // Dog 객체를 Animal 타입으로 참조
animal.eat(); // Dog의 eat() 메서드 호출 (다형성)
// animal.bark(); // 컴파일 에러: Animal 타입에는 bark() 메서드가 없음
// ((Dog) animal).bark(); // 강제 형변환을 통해 Dog의 bark() 메서드 호출
}
}
(4) 추상화(Abstraction)
추상화는 객체에서 핵심적인 특징을 추출하여 간단하게 표현하는 것을 의미한다. 클래스와 인터페이스를 통해 객체의 공통된 속성과 행위를 정의하고 구체적인 구현은 각각의 객체에 맡긴다.
// 추상화 예제: Shape 추상 클래스와 Circle 클래스
abstract class Shape {
abstract double area(); // 추상 메서드: 도형의 넓이를 계산하는 메서드
}
// Shape 클래스를 상속받는 Circle 클래스
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
double area() {
return Math.PI * radius * radius; // 원의 넓이 계산
}
}
■
4. 객체지향적 설계 원칙 - SOLID
▶ SRP(Single Responsibility Principle, 단일 책임 원칙)
: 각 클래스는 하나의 책임만 가져야 하며, 수정 이유는 단 하나여야 한다.
▶ OCP(Open/Closed Principle, 개방-폐쇄 원칙)
: 수정에는 닫혀 있고(Open for Extension), 확장에는 열려 있어야(Closed for Modification) 한다.
▶ LSP(Liskov Substitution Principle, 리스코프 치환 원칙)
: 자식 클래스는 부모 클래스의 대체 가능성을 유지해야 한다.
▶ ISP(Interface Segregation Principle, 인터페이스 분리 원칙)
: 클라이언트는 자신이 사용하지 않는 메서드에 의존하지 않아야 한다.
▶ DIP(Dependency Inversion Principle, 의존성 역전 원칙)
: 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안 되며, 양쪽 모두 추상화에 의존해야 한다.
■
5. 객체지향의 장점과 단점
▶장점
①객체 모듈화 및 재사용성
: 객체 단위로 모듈화, 각 객체는 독립적이고 재사용 가능한 모듈로써 다른 프로그램에서도 쉽게 사용할 수 있다.
②코드의 재사용성
: 상속을 통해 기존의 코드를 재사용할 수 있다.
③유지보수
: 캡슐화를 통해 객체의 내부 구현을 외부에 감춤으로써, 객체 내부의 변경이 외부에 영향을 미치지 않도록 한다.
④유연성 (Flexibility)
: 다형성을 통해 동일한 인터페이스를 가진 객체가 여러 형태로 구현될 수 있습니다.
▶단점
① 성능: 프로세스와 메모리 요구량이 더 많을 수 있다. (객체 생성과 관리, 가비지 컬렉션 비용, 상속과 다형성의 오버헤드 등)
② 설계의 복잡성: 각 객체의 역할, 책임, 관계 등을 명확하게 정의해야한다.
③ 적절하지 않은 사용: 객체지향 프로그래밍을 잘못 사용할 경우, 지나치게 복잡하거나 비효율적인 코드가 작성될 수 있다.
'JAVA' 카테고리의 다른 글
| > [Java] 직렬화 (Serializable) 에 대해서 3. Java 객체 직렬화/역직렬화 방법(Json, YAML, binary ) - GSON, YAML Bean, Protocol Buffers 등 (0) | 2020.12.14 |
|---|---|
| > [Java] 직렬화 (Serializable) 에 대해서 2. 의문점과 답변 정리 (0) | 2020.10.02 |
| > [Java] 직렬화 (Serializable) 에 대해서 1. 개념과 구현 (0) | 2020.09.22 |
| >[Java] static, final, 상수 개념과 사용 (0) | 2020.07.19 |
| > JVM(Java Virtual Machine): 아키텍처 및 성능 분석 (0) | 2020.07.13 |