⚠️개인이 학습한 것을 바탕으로 작성되어 부정확할 수 있으며, 오류가 있다면 알려주시면 감사하겠습니다.
자바에서 젤 중요 키워드인 객체지향에 대해서 정리해봤다.
평소에 알고있긴한 내용인데 사실 글로 적으라고하면 엄..하고 잠깐 버퍼링 걸리는데 ㅋㅋ
포스팅하면서 한번더 머리에 넣는 계기가 되었다.
객체지향이란?
객체 지향 프로그래밍 (Object-Oriented Programming, OOP)은 프로그램을 구성하는 요소들을 객체라는 단위로 보고, 객체들 간의 상호 작용을 통해 로직을 구성하는 프로그래밍 방법
객체 지향 프로그래밍의 장점
- 유지보수 용이 - 객체 단위로 코드가 구성되어 있어 변경이나 수정이 용이
- 재사용성 증가 - 객체는 재사용이 가능하여 개발 시간을 단축
- 확장성 용이 - 객체 간의 관계를 통해 새로운 기능을 쉽게 추가
- 코드의 모듈화 - 객체 단위로 코드가 구성되어 있어 코드의 모듈화
절차지향 vs 객제지향 비교
보통 객체지향 프로그래밍은 절차 지향 프로그래밍과 비교된다.
절차지향은 명령어의 순서대로 프로그램을 실행하는 방식인데 (대표로 C언어) , 객체지향은 객체간의 상호작용을 통한 프로그램을 구성하는 방식이다.
객체지향언어를 가지고도 활용을 못하면 절차지향 수준으로 밖에 코드를 짤수없는데..
이것이 개발자의 역 량 ㅋ이라고 생각한다.. ㅜㅜ~~!
1. 캡슐화
데이터와 기능을 함께 묶어 외부에서 함부로 접근하지 못하도록 보호하는 특징
- 데이터(필드)와 기능(메서드)을 하나의 클래스로 묶고, 외부로부터 숨김
- 외부는 메서드를 통해서만 객체 내부 상태를 변경/조회할 수 있음
접근제어자
`private`: 외부 접근 차단 (캡슐화의 핵심)
| 제어자 | 같은 클래스 | 같은 패키지 | 하위 클래스 | 외부 클래스 |
| `public` | O | O | O | O |
| `protected ` | O | O | O | X |
| `default` | O | O | X | X |
| `private` | O | X | X | X |
Getter/Setter의 역할
//데이터를 안전하게 읽고 쓸 수 있도록 통제
private String name;
public String getName() {
return name;
}
public void setName(String name) {
if (name != null && name.length() > 0) this.name = name;
}
무분별한 Setter의 위험
- 모든 필드를 `public Setter`로 열면 캡슐화 무력화
- 검증 없이 내부 상태 변경 가능하다면 오류/버그 증가한다 주의 또 주의 !!!
(회사에서는 내가만든 클래스나 함수를 남이쓰기도하는데 절대 바뀌지말아야할 것들에 접근을 못하게하거나 final이나 static키워드를 알맞게 붙혀놔야한다. 누가 가져다썻는데 문제생기면 무조건 클래스나 함수 만든사람 탓임 뭔지도 모르고 가져쓴사람도 잘못이긴함ㅋㅋ 나같은경우는 이게 먼가..싶으면 걍 새로만들음 ㅜㅜㅋ )
2. 상속
기존 객체의 특징을 이어받아 새로운 객체를 만들 수 있도록 하는 특징
상위 클래스의 필드/메서드를 하위 클래스가 "물려받아" 사용할 수 있는 구조
울회사 같은경우는 CommonVo를 상속(`extends`)받아서 각각의 객체를 활용할 수있는 구조를 많이쓴당
활용 목적
- 공통 기능을 상위 클래스에 정의하여 코드 중복 제거
- 하위 클래스는 기능을 추가하거나 오버라이딩 가능
class Animal {
void eat() { System.out.println("먹는다"); }
}
class Dog extends Animal {
void bark() { System.out.println("짖는다"); }
}
super / super()
- `super`: 부모 메서드/필드에 접근
- `super()`: 부모 생성자 호출 (자식 생성자 첫 줄에만 위치 가능!! -> 당연히 자식이생성되기전에 부모가 생성되는게 먼저)
오버라이딩 (Overriding)
- 부모 메서드를 자식이 재정의
- 조건: 메서드명, 매개변수, 리턴타입 동일 + 접근 제한자 범위 동일 또는 확대
@Override
void eat() {
System.out.println("사료 먹는다");
}
⚠️ 오버라이딩 vs 오버로딩
| 항목 | 오버라이딩 (Overriding) | 오버로딩 (Overloading) |
| 정의 | 상속받은 부모 메서드를 재정의 | 같은 이름의 메서드를 매개변수만 다르게 여러개 정의 * 리턴값만 다른 것은 오버로딩을 할 수 없 |
| 시점 | 실행 시 결정 (Runtime) | 컴파일 시 결정 (Compile-time) |
| 메서드 이름 | 같음 | 같음 |
| 매개변수 | 완전히 동일 | 개수/타입이 달라야 함 |
| 리턴 타입 | 동일 or 자식 타입 (Java 5 이상 공변 리턴 허용) | 달라도 무방 |
| 위치 | 부모-자식 클래스 간 | 같은 클래스 내 |
| 어노테이션 사용 | `@Override` 사용 권장 (오버라이딩이 잘못된경우 컴파일오류, 가시성) |
X |
| 대표 예시 | ` toString() ` , ` equals()` (객체의 표현을 변경하거나 객체 비교를 해야하는데 Object 클래스의 메서드이기때문에 내가 원하는 값의 모양으로 출력하거나 내가 원하는 값을 비교하도록 오버라이딩 해야 유의미함!! ) |
` System.out.println() ` , ` String.valueOf() ` 등 (다양한 기본형 혹은 객체를 받아서 사용해야하기때문에 모두 같은이름이지만 매개변수 타입이 다름) |
| 장점 | 상위 클래스의 필드/메서드를 하위 클래스가 물려받아 공통으로 사용할 수 있는 구조 (코드 중복제거) | - 같은 기능을 하는 메서드를 하나의 이름으로 사용할 수 있기 때문 - 메서드의 이름을 절약 |
3. 추상화
복잡한 세부 사항을 숨기고 핵심적인 특징만 드러내어 객체를 단순화하는 특징
불필요한 구현 세부사항은 숨기고, 핵심 인터페이스만 제공
실사용으로는 추상 클래스에
public abstract class CodeManager
{
public static final String AAAA = "값"
public static String doService(String serviceUrl, String requestXml){
//어쩌고 저쩌고~
}
}
이런식으로 상수 모아놓고 다른 곳에서 불러쓰기도하고 기본적인 메서드를 만들어서 불러다 쓰기도한다.
=> 기본 구현 제공..
인터페이스는
public class ABCVO implements Comparable<ABCVO>{
//변수~
//비교
@Override
public int compareTo( ABCVO aBCVO ) {}
}
//유효하지 않은 서비스키 예외처리시 활용
public class InvalidServiceKeyException extends Exception implements IExceptionHeader {
}
이런식으로 비교 `Comparable<>` 인터페이스를 쓰기도하구 보통 인터페이스를 만드는거같지는않고 자바 내부의 것들을 활용한다. 예를들면 `java.io.Serializable` (직렬화) 라던가 `java.rmi.Remote`(리모트 통신)
=> 계약(기능 명세) 제공
활용1. 추상 클래스 (abstract class)
- 일부 구현 포함 가능
- `abstract` 키워드로 선언, 객체 직접 생성 불가
abstract class Shape {
abstract void draw();
}
class Circle extends Shape {
void draw() { System.out.println("원을 그린다"); }
}
활용2. 인터페이스 (interface)
- 전부 추상 메서드만 가짐 (Java 8부터는 default/static 허용)
- 다중 구현 가능 → 유연한 구조 설계
interface Drawable {
void draw();
}
추상화의 목적
- 구조를 명확히 정의 (계약 기반 설계)
- 구현과 사용의 분리 → 유지보수와 확장성 향상
⚠️추상클래스와 인터페이스 차이점
- 상속이 계층적 구조를 선언하기 적합합니다.
- 인터페이스는 표준을 제공하는 데 적합합니다.
- 인터페이스는 인스턴스 변수를 선언할 수 없습니다.
- 계층적 구조를 표현하면서 공통 속성과 기능을 재사용할 때 추상클래스를 사용하는것이 적합합니다.
항목 추상클래스 인터페이스 다중 상속 불가능 가능 상태(필드) 보유 O X (상수만 가능) 구현 메서드 일부 구현 가능 Java 8부터 default/static 허용 -하위 호환성 유지 목적 목적 기본 구현 제공 계약(기능 명세) 제공
//static 메서드 : 인터페이스 자체에서 호출 가능한 정적 메서드
//구현 객체가 없어도 사용할 수 있어, 도우미 기능(유틸성 기능) 제공에 유용함
interface MyInterface {
static void help() {
System.out.println("도움말 보기");
}
}
//default 메서드 : 인터페이스에 '기본 구현'을 추가할 수 있는 메서드
//이 메서드를 구현 클래스에서 선택적으로 오버라이딩 가능
interface MyInterface {
default void greet() {
System.out.println("안녕하세요 (기본 인사)");
}
}
4. 다형성
하나의 타입(참조변수)으로 여러 객체를 다룰 수 있음
실행 시점에 실제 객체 타입에 따라 동작이 달라짐
Animal a = new Dog();
a.eat(); // Dog의 eat()이 실행됨
업캐스팅 (UpCasting)
- 자식 → 부모 타입으로 형 변환 (자동)
- 다형성의 기본: 인터페이스/상위클래스 타입 변수로 하위 객체 참조
다운캐스팅 (DownCasting)
- 부모 → 자식 타입으로 형 변환 (강제)
//instanceof로 타입 검사 필수
if (a instanceof Dog) {
Dog d = (Dog) a;
d.bark();
}
다형성의 장점
- 확장성 있는 코드 작성 가능
- 동일한 코드가 다양한 결과를 유연하게 생성 → 전략 패턴, DI 구조 등 기반
'공부일기.. > Java' 카테고리의 다른 글
| [TDD](TDD기반 서비스 개발 후) 회고 및 객체지향 설계 고민 (0) | 2025.07.12 |
|---|---|
| [TDD] JUnit 테스트 입문 – Mockito로 실제 객체 vs Mock 비교 (0) | 2025.07.11 |
| [TDD] TDD 테스트 방법론 (0) | 2025.07.11 |
| 스트림(Stream) / Optional<T> / 람다 (0) | 2025.07.03 |
| JVM 메모리영역 (6) | 2025.06.19 |