Java ‐ OOP - dnwls16071/Backend_Summary GitHub Wiki

📚 final 키워드

  • 변수, 메서드, 클래스에 사용되어 변경을 제한하는 역할
  • final 변수 : 값을 변경할 수 없음
  • final 메서드 : 오버라이딩 불가능
  • final 클래스 : 상속 불가능

❗final 키워드는 필수는 아니지만, 코드의 안정성과 명확성을 높여주는 매우 유용한 도구이다. ❗기본적으로 final을 붙이는 것을 강력히 권장한다. 클래스의 멤버 변수는 객체의 상태를 나타내므로, 불필요하게 변경될 여지를 남기지 않는 것이 좋다.

  • 변경될 이유가 없는 변수: 객체가 생성될 때 초기화된 후 그 값이 계속 유지되어야 하는 변수에는 반드시 final을 붙여준다.
  • 의도적으로 변경해야 하는 변수: 객체의 상태가 변해야 하는 경우 (예: 사용자의 나이, 계좌 잔액 등)에만 final을 생략한다.

❗메서드 내에서 선언되는 지역 변수의 경우, 의견이 다소 나뉘지만, 값을 재할당할 필요가 없다면 final을 붙이는 것이 좋은 습관이다.

  • 한 번만 값을 할당하는 변수: 메서드 내에서 선언과 동시에, 또는 한 번만 값을 할당하고 그 이후로는 읽기만 하는 변수에는 final을 붙여준다.
  • 반복문 등에서 값이 계속 바뀌는 변수: 반복문의 카운터 변수처럼 값이 계속 변경되어야 하는 경우에는 당연히 final을 사용할 수 없다.

❗메서드에 전달되는 매개변수에 final을 붙이면, 메서드 내부에서 해당 매개변수의 값을 재할당하는 것을 방지할 수 있다.

📚 다형성(Polymorphism)

  • 같은 인터페이스나 부모 클래스를 공유하는 객체가 서로 다른 동작을 수행할 수 있는 성질
  • 메서드 호출 시, 실행될 구체적인 구현이 실행 시점에 결정된다.
// 메서드 오버라이딩을 통한 다형성 - 부모 클래스 메서드를 자식 클래스에서 재정의해 다른 동작을 수행하도록 구현
class Animal {
    void makeSound() {
        System.out.println("Some sound");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Bark!");
    }
}
Animal myDog = new Dog();
myDog.makeSound(); // 실행 결과: Bark! (Dog의 메서드 실행)
// 인터페이스를 통한 다형성 - 인터페이스를 구현한 여러 클래스가 같은 메서드를 다르게 구현할 수 있다.
interface Shape {
    void draw();
}

class Circle implements Shape {
    public void draw() {
        System.out.println("Drawing Circle");
    }
}

class Square implements Shape {
    public void draw() {
        System.out.println("Drawing Square");
    }
}

Shape s1 = new Circle();
Shape s2 = new Square();
s1.draw();
s2.draw();

📚 인터페이스 vs 추상 클래스

항목 인터페이스 추상 클래스
상속 방식 다중 구현 가능 단일 상속만 가능(댜이아몬드 문제)
구현 여부 모든 메서드가 추상 일부만 구현 가능
목적 기능 명세(API) 공통 기능 제공 및 강제 구현 유도
키워드 interface abstract class
// 인터페이스
interface AnimalActions {
    void eat(); // public abstract 생략됨
}

class Dog extends Animal implements AnimalActions {
    @Override
    void makeSound() {
        System.out.println("Bark!");
    }
 
    @Override
    public void eat() {
        System.out.println("Eating...");
    }
}

// 추상 클래스
abstract class Animal {
    abstract void makeSound();
    void sleep() {
        System.out.println("Sleeping...");
    }
}