객체지향 프로그래밍은 현실 세계를 반영하여 사물(객체)의 속성과 행위를 기준으로 소프트웨어를 구성하는 방식입니다. OOP의 기본 단위는 객체이며, 객체는 속성과 행위를 갖는 실체입니다.
클래스는 객체를 생성하기 위한 설계도입니다. 클래스 내부에는 변수(필드), 생성자, 메서드가 포함됩니다.
public class Car {
String color;
int speed;
void accelerate() {
speed += 10;
}
void brake() {
speed -= 10;
}
}
객체는 클래스를 기반으로 생성된 실체로, 메모리 상에 실제로 존재합니다. 클래스에 정의된 속성과 동작을 가지고 있습니다.
Car myCar = new Car();
myCar.color = "Blue";
myCar.accelerate();
객체 내부의 상태(필드)를 외부에서 직접 접근하지 못하도록 하고, 메서드를 통해서만 접근하도록 제한하는 방식입니다. 정보은닉이라고도 합니다.
public class Person {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
이렇게 하면 객체의 상태를 보호하고, 잘못된 접근을 방지할 수 있습니다.
기존의 클래스를 기반으로 새로운 클래스를 생성하는 기능입니다. 코드 재사용을 가능하게 해주며, 공통된 기능을 상위 클래스에 정의해놓고 하위 클래스에서 활용하거나 확장할 수 있습니다.
public class Animal {
void eat() {
System.out.println("먹는다");
}
}
public class Dog extends Animal {
void bark() {
System.out.println("멍멍");
}
}
하나의 메서드나 클래스가 다양한 형태로 동작할 수 있는 성질입니다. 자바에서는 오버로딩(overloading)과 오버라이딩(overriding)으로 구현됩니다.
오버로딩: 같은 이름의 메서드를 매개변수에 따라 다르게 정의
오버라이딩: 부모 클래스의 메서드를 자식 클래스에서 재정의
class Animal {
void sound() {
System.out.println("소리를 낸다");
}
}
class Cat extends Animal {
@Override
void sound() {
System.out.println("야옹");
}
}
Animal a = new Cat();
a.sound(); // 실행 시점에 Cat의 sound() 호출
복잡한 구현은 감추고 필요한 기능만 노출하여 설계하는 방식입니다. 추상 클래스나 인터페이스를 통해 구현합니다.
abstract class Shape {
abstract void draw();
}
class Circle extends Shape {
void draw() {
System.out.println("원을 그림");
}
}
|
요소 |
설명 |
|---|---|
|
클래스 |
객체를 생성하기 위한 설계도 |
|
객체 |
클래스 기반으로 생성된 메모리 내 실체 |
|
필드 |
객체가 가지는 속성(데이터) |
|
메서드 |
객체가 수행할 수 있는 동작 |
|
생성자 |
객체 생성 시 호출되는 특수한 메서드 |
|
접근 제어자 |
접근 범위를 설정하는 키워드 (public, private 등) |
모듈화: 객체 단위로 코드가 분리되어 구조가 명확함
재사용성: 클래스와 상속을 통해 코드 재사용이 가능함
확장성: 기존 코드를 수정하지 않고도 기능 확장이 쉬움
유지보수성: 캡슐화를 통해 변경이 필요한 부분만 수정 가능함
현실 세계 모델링: 직관적인 설계가 가능하여 복잡한 문제도 구조화 가능
|
항목 |
절차지향 |
객체지향 |
|---|---|---|
|
중심 개념 |
함수(절차) 중심 |
객체 중심 |
|
설계 방식 |
순차적 명령 흐름 |
클래스와 객체로 구조화 |
|
코드 재사용 |
낮음 |
상속, 인터페이스 등으로 높음 |
|
유지보수성 |
전체 코드 영향 |
모듈화되어 부분 유지보수 가능 |