Java OOP
자바 객체 지향 프로그래밍 (OOP): 기본 개념과 원칙
자바(Java)는 객체 지향 프로그래밍(Object-Oriented Programming, OOP)을 기반으로 설계된 언어입니다. OOP는 현실 세계의 객체를 프로그래밍에 반영하여 문제를 더 직관적이고 효율적으로 해결할 수 있도록 도와줍니다. 이 글에서는 자바에서 OOP의 기본 개념과 주요 원칙을 설명하고, 이를 이해하는 데 도움이 되는 예제도 함께 제공합니다.
객체 지향 프로그래밍이란?
객체 지향 프로그래밍은 프로그램을 객체(Object)와 그 객체 간의 상호작용으로 구성하는 프로그래밍 패러다임입니다. 여기서 객체는 상태와 행동을 가지는 독립적인 단위입니다.
OOP의 4가지 주요 원칙
- 캡슐화(Encapsulation): 객체의 속성과 메서드를 하나의 단위로 묶고, 외부에서 접근할 수 있는 범위를 제한합니다.
- 상속(Inheritance): 기존 클래스의 속성과 메서드를 재사용하여 새로운 클래스를 정의할 수 있습니다.
- 다형성(Polymorphism): 하나의 인터페이스나 메서드가 여러 형태를 가질 수 있습니다.
- 추상화(Abstraction): 객체의 복잡성을 숨기고 중요한 정보만 외부에 노출시킵니다.
1. 캡슐화 (Encapsulation)
캡슐화는 객체의 데이터를 외부에서 직접 접근하지 못하도록 보호하고, 이를 위해 접근자 메서드(게터와 세터)를 사용해 데이터를 제어하는 방식입니다. 이를 통해 데이터의 무결성을 유지할 수 있습니다.
캡슐화 예제
class Person {
private String name; // private 변수, 외부에서 직접 접근 불가
private int age;
// 생성자
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getter와 Setter 메서드
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 0) { // 나이는 0보다 커야 한다는 조건을 추가
this.age = age;
}
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("John", 30);
System.out.println(person.getName()); // 출력: John
person.setAge(25);
System.out.println(person.getAge()); // 출력: 25
}
}
캡슐화의 장점
- 데이터 보호: 외부에서 직접 접근하지 못하도록 데이터를 보호할 수 있습니다.
- 유지보수성: 내부 구현이 변경되어도 외부 코드에 영향을 주지 않으므로 유지보수가 용이합니다.
2. 상속 (Inheritance)
상속은 기존 클래스의 특성을 물려받아 새로운 클래스를 생성하는 기능입니다. 상속을 사용하면 코드의 재사용성을 높이고, 유지보수를 쉽게 할 수 있습니다.
상속 예제
class Animal {
protected String name;
public void eat() {
System.out.println(name + " is eating.");
}
}
class Dog extends Animal {
public Dog(String name) {
this.name = name;
}
public void bark() {
System.out.println(name + " is barking.");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Buddy");
dog.eat(); // 출력: Buddy is eating.
dog.bark(); // 출력: Buddy is barking.
}
}
상속의 장점
- 코드 재사용: 상속을 통해 기존 코드를 재사용할 수 있습니다.
- 유지보수 용이성: 상속된 클래스에서만 기능을 추가하거나 변경하면 됩니다.
3. 다형성 (Polymorphism)
다형성은 하나의 메서드나 객체가 여러 가지 형태를 가질 수 있는 것을 의미합니다. 다형성에는 두 가지 형태가 있습니다:
- 컴파일 타임 다형성 (오버로딩)
- 런타임 다형성 (오버라이딩)
오버로딩 예제 (컴파일 타임 다형성)
class Calculator {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(calc.add(3, 4)); // 출력: 7
System.out.println(calc.add(3.5, 4.5)); // 출력: 8.0
}
}
오버라이딩 예제 (런타임 다형성)
class Animal {
public void sound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
animal.sound(); // 출력: Bark
}
}
다형성의 장점
- 코드의 유연성: 동일한 메서드를 다양한 객체에서 사용할 수 있습니다.
- 확장성: 새로운 클래스를 추가할 때 기존 코드를 수정하지 않고도 기능을 확장할 수 있습니다.
4. 추상화 (Abstraction)
추상화는 객체의 복잡한 구현을 숨기고, 필요한 부분만 외부에 노출하는 것을 의미합니다. 자바에서는 추상 클래스와 인터페이스를 통해 추상화를 구현할 수 있습니다.
추상 클래스 예제
abstract class Vehicle {
abstract void start(); // 추상 메서드
public void stop() {
System.out.println("Vehicle stopped.");
}
}
class Car extends Vehicle {
@Override
void start() {
System.out.println("Car started.");
}
}
public class Main {
public static void main(String[] args) {
Vehicle car = new Car();
car.start(); // 출력: Car started.
car.stop(); // 출력: Vehicle stopped.
}
}
추상화의 장점
- 복잡성 감소: 객체의 내부 구현을 숨기고 중요한 기능만 외부에 제공함으로써 복잡성을 줄일 수 있습니다.
- 유지보수성: 추상화된 코드는 변경이 적고 유지보수가 더 쉽습니다.
요약
자바의 객체 지향 프로그래밍(OOP)은 캡슐화, 상속, 다형성, 추상화라는 네 가지 핵심 원칙을 기반으로 합니다. 이 원칙들을 사용하면 코드의 재사용성, 유지보수성, 확장성을 높일 수 있으며, 더 효율적이고 직관적인 프로그램을 작성할 수 있습니다. OOP 개념을 잘 이해하고 활용하는 것이 자바 프로그래밍을 더 깊이 이해하는 데 중요한 첫걸음입니다.