9. 객체 지향 프로그래밍(object-oriented programming(OOP))

MYUNGSUN·2024년 2월 19일
0

스프링부트

목록 보기
9/16

📌 객체 지향 프로그래밍?

object-oriented programming(OOP)

프로그램 설계방법론의 일종으로, 명령형 프로그래밍에 속한다.

프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라, 프로그램을 수많은 '객체(object)'라는 기본 단위로 나누고 이들의 상호작용으로 서술하는 방식이다. 객체란 '메소드와 변수'를 가지며, 특정 역할을 수행하도록 인간이 정의한, 추상적인 개념이다.

📌 객체 지향 프로그래밍의 특징

✔️ 1. 캡슐화(Encapsulation) - 데이터 보호

만약 계좌를 프로그래밍 한다고 예시를 들어보자

public class Account {
    private String accountNumber; // 계좌번호
    private String owner; // 소유주
    private int balance; // 잔액
}

계좌라는 객체는 소유주/잔액이라는 두 개의 중요한 데이터를 "캡슐화" 한다.
소유주와 잔액을 객체 내부에서 private로 선언되고, 외부에선 이 데이터에 직접적으로 접근할 수 없다.

✔️ 2 . 추상화(Abstraction) - 핵심적인 코드만 보여주기

// 생성자
    public Account(String accountNumber, String owner) {
        this.accountNumber = accountNumber;
        this.owner = owner;
        this.balance = 0; // 잔액 초기화
    }
    
    // 입금 메서드
    public void deposit(int amount) {
        balance += amount;
    }
    
    // 출금 메서드
    public void withdraw(int amount) {
        if (amount > balance) {
            System.out.println("잔액이 부족합니다");
        } else {
            balance -= amount;
        }
    }
    
    // 잔액 조회 메서드
    public int getBalance() {
        return balance;
    }

atm기기의 내부 동작 하는 코드

public class Main {
    public static void main(String[] args) {
        // 은행 계좌 객체 생성
        Account account1 = new Account("123-456-789", "John Doe");
        
        // 입금
        account1.deposit(10000);
        
        // 출금
        account1.withdraw(5000);
        
        // 잔액 조회
        int balance = account1.getBalance();
        System.out.println("잔액: " + balance);
    }
}

사용자 입장에서의 atm기기

사용자 입장에선 내부 코드가 어떻게 돌아가는지는 알 필요 없다.
입금/출금/잔액조회의 내부동작 방식을 메서드로 정의 해두는게 추상화라고 볼 수 있다.

✔️ 3. 상속 (Inheritance) - 코드 재사용

// 하위 클래스: 보통 계좌(NormalAccount)
public class NormalAccount extends Account {
    // 보통 계좌는 수수료를 부과하여 출금한다고 가정
    @Override
    public void withdraw(int amount) {
        int fee = 1000; // 출금 수수료
        if (amount + fee > balance) {
            System.out.println("잔액이 부족합니다");
        } else {
            balance -= (amount + fee);
        }
    }
}

// 하위 클래스: 적금 계좌(SavingsAccount)
public class SavingsAccount extends Account {
    // 적금 계좌는 이자가 발생한다고 가정
    private double interestRate; // 이자율
    
    // 생성자, getter, setter 등 생략
    
    public void addInterest() {
        double interest = balance * interestRate;
        deposit((int)interest);
    }
}

아까 쓰였던 Account를 상속 받아 재사용하고, 기능만 추가한다면 편리하게 재사용할 수 있다!

✔️ 4. 다형성(Polymorphism) - 객체 변경 용이

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("야옹");
    }
}
  1. 오버라이딩(Overriding)
    위의 코드에서 Animal 클래스를 상속받는 Dog 클래스와 Cat 클래스가 있다. 각각의 클래스에서는 sound() 메서드를 재정의하여 동물의 소리를 다르게 출력하는데, 이렇게 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것을 오버라이딩이다.
Animal dog = new Dog();
Animal cat = new Cat();
  1. 업캐스팅(Upcasting)
    위의 코드에서는 Dog와 Cat 객체를 Animal 타입의 변수에 할당하고 있다. 이렇게 자식 클래스의 인스턴스를 부모 클래스의 참조 변수에 할당하는 것을 업캐스팅이라고 한다. 이렇게 하면 다형성의 개념이 적용되어, Animal 변수로서 dog와 cat 객체를 모두 참조할 수 있게 된다!

    업캐스팅 후, dog.sound();를 하게되면 "멍멍" 이 나오게 된다.


class Animal {
    public void eat() {
        System.out.println("동물이 먹는다.");
    }
}

class Dog extends Animal {
    public void bark() {
        System.out.println("멍멍!");
    }
}
Animal myAnimal = new Dog();

메서드 오버라이딩없이 업캐스팅만 한다면?

myAnimal.eat(); // 가능: Animal 클래스에 있는 메서드에 접근
myAnimal.bark(); // 불가능: Dog 클래스에만 있는 메서드에 접근

이것이 업캐스팅을 통해 하위 클래스를 상위 클래스로 변환하면, 상위 클래스에만 있는 속성과 메서드에만 접근할 수 있게 되는 원리이다! 그러므로 오버라이딩과 업캐스팅 함께 사용해주어야 비로소 다형성이다.

profile
백엔드

0개의 댓글

관련 채용 정보