[Java] 객체 지향 프로그래밍 캡슐화, 상속, 다형성, 추상화에 대해서
KUKJIN LEE • 2개월 전 작성
객체 지향 프로그래밍(OOP, Object-Oriented Programming)은 프로그램을 객체(object)라는 단위로 나누어 개발하는 방식입니다. 객체는 상태(필드)와 행동(메서드)을 가지며, 실제 세계의 사물이나 개념을 추상화하여 코드로 표현할 수 있습니다.
OOP는 코드의 재사용성과 유지보수성을 높이며, 복잡한 시스템을 더 쉽게 관리할 수 있게 해줍니다. 객체들 간의 상호작용을 통해 프로그램이 실행되며, 이 과정에서 네 가지 주요 원칙(캡슐화, 상속, 다형성, 추상화)이 중요한 역할을 합니다.
OOP의 4대 원칙
-
캡슐화(Encapsulation): 객체의 내부 상태(필드)를 외부에서 직접 접근하지 못하도록 보호하고, 대신에 메서드를 통해 접근하도록 하는 원칙입니다. 이를 통해 객체의 상태를 안전하게 관리하고, 불필요한 외부 간섭을 방지할 수 있습니다.
class Car {
private String model; // 외부에서 직접 접근 불가
private int year;
public Car(String model, int year) {
this.model = model;
this.year = year;
}
// 외부에서 접근 가능한 메서드 제공
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
-
상속(Inheritance): 기존 클래스의 속성과 기능을 물려받아 새로운 클래스를 정의하는 원칙입니다. 이를 통해 코드의 중복을 줄이고, 공통 기능을 상속받아 재사용할 수 있습니다. 부모 클래스의 특성을 자식 클래스가 상속받으며, 자식 클래스는 필요한 경우 부모 클래스의 기능을 확장하거나 수정할 수 있습니다.
class Vehicle {
protected String brand = "Ford"; // Vehicle의 속성
public void honk() { // Vehicle의 메서드
System.out.println("Vehicle is honking!");
}
}
class Car extends Vehicle {
private String modelName = "Mustang"; // Car의 속성
public String getModelName() {
return modelName;
}
}
public class Main {
public static void main(String[] args) {
Car myCar = new Car();
System.out.println(myCar.brand); // 상속받은 Vehicle의 속성
System.out.println(myCar.getModelName()); // Car의 속성
myCar.honk(); // 상속받은 Vehicle의 메서드
}
}
-
다형성(Polymorphism): 하나의 객체가 여러 형태를 가질 수 있는 원칙을 의미합니다. 즉, 동일한 메서드가 객체에 따라 다르게 동작할 수 있도록 하는 기능입니다. 이를 통해 코드의 유연성과 확장성을 높일 수 있습니다. 다형성은 주로 메서드 오버라이딩(Method Overriding)과 인터페이스 구현에서 나타납니다.
쉽게 말해, 클래스에서 각기 다르게 오버라이딩하여, 같은 메서드를 호출하더라도 객체의 타입에 따라 다른 결과가 출력됩니다.
class Animal {
public void sound() {
System.out.println("동물이 소리를 냅니다.");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("개가 짖습니다.");
}
}
class Cat extends Animal {
@Override
public void sound() {
System.out.println("고양이가 웁니다.");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal(); // 부모 클래스 인스턴스
Animal myDog = new Dog(); // Dog 클래스 인스턴스 (다형성)
Animal myCat = new Cat(); // Cat 클래스 인스턴스 (다형성)
myAnimal.sound(); // 동물이 소리를 냅니다.
myDog.sound(); // 개가 짖습니다.
myCat.sound(); // 고양이가 웁니다.
}
}
-
추상화(Abstraction): 객체의 복잡성을 숨기고, 필요한 부분만을 외부에 노출하는 원칙입니다. 추상화는 인터페이스와 추상 클래스를 통해 구현할 수 있으며, 구현 세부 사항을 감추고 중요한 기능만을 정의할 수 있습니다. 이를 통해 복잡한 시스템을 더 간결하게 표현할 수 있습니다.
핵심은 부모 클래스(추상 클래스)에서 구체적인 구현을 정의하지 않고, 이를 상속받는 자식 클래스에서 구체적인 기능을 직접 구현하도록 하는 것입니다.
abstract class Shape {
// 추상 메서드 (구체적인 구현이 없음)
abstract void draw();
}
class Circle extends Shape {
@Override
void draw() {
// Circle 클래스에서 draw 메서드의 구체적인 구현
System.out.println("원을 그립니다.");
}
}