본문 바로가기
자바 (JAVA)

📚 JAVA 6강: 객체 지향 프로그래밍 (OOP) - 상속과 오버라이딩

by demianpark127 2025. 1. 3.
SMALL

📚 6강: 객체 지향 프로그래밍 (OOP) - 상속과 오버라이딩


🚀 1. 상속(Inheritance)

📌 1.1 상속이란?

  • **상속(Inheritance)**은 **기존 클래스(부모 클래스)**의 속성과 메서드를 **새로운 클래스(자식 클래스)**가 물려받는 기능입니다.
  • 코드 재사용성을 높이고 유지보수를 용이하게 합니다.

📌 1.2 상속의 기본 문법

상속 선언

class 부모클래스 {
    // 부모 클래스의 멤버 변수와 메서드
}

class 자식클래스 extends 부모클래스 {
    // 부모의 모든 멤버를 상속받음
}

예제 코드

class Animal {
    String name;

    void eat() {
        System.out.println(name + "가 먹고 있습니다.");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println(name + "가 짖습니다.");
    }
}

public class InheritanceExample {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "멍멍이";
        dog.eat(); // 부모 클래스 메서드
        dog.bark(); // 자식 클래스 메서드
    }
}

📌 출력 결과:

멍멍이가 먹고 있습니다.
멍멍이가 짖습니다.

📌 1.3 상속의 특징

  1. 단일 상속: Java는 **단일 상속(Single Inheritance)**만 지원합니다.
  2. super 키워드: 부모 클래스의 멤버에 접근할 때 사용합니다.
  3. 다형성(Polymorphism): 상속을 통해 다형성을 구현할 수 있습니다.

🚀 2. super 키워드

  • super는 부모 클래스의 멤버 변수나 메서드에 접근할 때 사용됩니다.
  • 생성자 호출 시 부모 생성자를 호출할 때 사용됩니다.

super 사용 예시

class Animal {
    String name;

    Animal(String name) {
        this.name = name;
    }

    void eat() {
        System.out.println(name + "가 먹고 있습니다.");
    }
}

class Dog extends Animal {
    Dog(String name) {
        super(name); // 부모 생성자 호출
    }

    void display() {
        System.out.println("강아지의 이름은 " + name + "입니다.");
    }
}

public class SuperExample {
    public static void main(String[] args) {
        Dog dog = new Dog("멍멍이");
        dog.eat();
        dog.display();
    }
}
📌 출력 결과:

멍멍이가 먹고 있습니다.
강아지의 이름은 멍멍이입니다.

 

🚀 3. 메서드 오버라이딩(Method Overriding)

📌 3.1 메서드 오버라이딩이란?

  • 자식 클래스가 부모 클래스의 메서드를 재정의하는 것입니다.
  • 부모 클래스의 메서드를 자식 클래스에서 새로운 기능으로 덮어씁니다.

📌 3.2 오버라이딩 문법

  • 메서드 이름, 반환형, 매개변수가 부모 클래스와 동일해야 합니다.
  • @Override 애너테이션 사용을 권장합니다.
class Animal {
    void sound() {
        System.out.println("동물이 소리를 냅니다.");
    }
}

class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("강아지가 멍멍 짖습니다.");
    }
}

public class OverridingExample {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.sound(); // 자식 클래스의 메서드 호출
    }
}
📌 출력 결과:

강아지가 멍멍 짖습니다.

🚀 4. 접근 제어자와 상속

제어자자식 클래스 접근 가능 여부

public O
protected O
default 같은 패키지 내에서만 접근 가능
private X (상속받아도 접근 불가)

🚀 5. final 키워드

  • final 키워드가 붙은 클래스는 상속 불가합니다.
  • final 키워드가 붙은 메서드는 오버라이딩 불가합니다.

final 사용 예시

final class Animal {
    void sound() {
        System.out.println("동물이 소리를 냅니다.");
    }
}

// 아래 코드는 오류 발생!
// class Dog extends Animal {}

class Bird {
    final void fly() {
        System.out.println("새가 날아갑니다.");
    }
}

class Sparrow extends Bird {
    // fly() 메서드 오버라이딩 불가
}

 

🚀 6. instanceof 연산자

  • instanceof는 객체가 특정 클래스의 인스턴스인지 확인합니다.

instanceof 예시

Animal dog = new Dog();

if (dog instanceof Dog) {
    System.out.println("dog는 Dog 클래스의 객체입니다.");
}
📌 출력 결과:

dog는 Dog 클래스의 객체입니다.

 

🚀 7. 실습 과제

1. 상속과 super 사용하기

  • Person 클래스를 만들고 name, age 속성을 추가합니다.
  • Student 클래스를 Person 클래스로부터 상속받고, school 속성을 추가합니다.
  • Student 생성자에서 super로 부모 생성자를 호출하세요.
// 부모 클래스: Person
class Person {
    String name;
    int age;

    // 생성자
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 정보 출력 메서드
    public void displayInfo() {
        System.out.println("이름: " + name + ", 나이: " + age);
    }
}

// 자식 클래스: Student
class Student extends Person {
    String school;

    // 생성자
    public Student(String name, int age, String school) {
        super(name, age); // 부모 생성자 호출
        this.school = school;
    }

    // 학생 정보 출력 메서드 (오버라이딩)
    @Override
    public void displayInfo() {
        super.displayInfo(); // 부모 클래스 메서드 호출
        System.out.println("학교: " + school);
    }
}

// 메인 클래스
public class Main {
    public static void main(String[] args) {
        // Student 객체 생성
        Student student = new Student("김철수", 20, "서울대학교");
        
        // 정보 출력
        student.displayInfo();
    }
}

✅ 4. 출력 결과

이름: 김철수, 나이: 20
학교: 서울대학교

2. 메서드 오버라이딩

  • Animal 클래스를 만들고 sound() 메서드를 정의하세요.
  • Dog와 Cat 클래스를 Animal로부터 상속받고, sound() 메서드를 오버라이딩하세요.
  • 각각의 sound() 메서드를 호출하세요.
// 부모 클래스: Animal
class Animal {
    // 메서드: sound()
    public void sound() {
        System.out.println("동물이 소리를 냅니다.");
    }
}

// 자식 클래스: Dog
class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("강아지가 멍멍 짖습니다.");
    }
}

// 자식 클래스: Cat
class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("고양이가 야옹 울습니다.");
    }
}

// 메인 클래스
public class Main {
    public static void main(String[] args) {
        // 부모 타입 참조 변수로 자식 객체 생성 (다형성)
        Animal myDog = new Dog();
        Animal myCat = new Cat();

        // 각각의 sound() 메서드 호출
        myDog.sound(); // Dog 클래스의 sound() 호출
        myCat.sound(); // Cat 클래스의 sound() 호출

        // 명확한 타입으로 객체 생성
        Dog dog = new Dog();
        Cat cat = new Cat();

        dog.sound(); // Dog 클래스의 sound() 호출
        cat.sound(); // Cat 클래스의 sound() 호출
    }
}

✅ 4. 출력 결과

강아지가 멍멍 짖습니다.
고양이가 야옹 울습니다.
강아지가 멍멍 짖습니다.
고양이가 야옹 울습니다.

🎯 학습 목표

  1. 상속의 개념과 장점을 이해한다.
  2. super 키워드를 사용해 부모 클래스의 멤버에 접근할 수 있다.
  3. 메서드 오버라이딩을 활용해 다형성을 구현할 수 있다.
  4. final 키워드의 역할을 이해한다.

다음 강의 예고: 7강 - 객체 지향 프로그래밍 (OOP) - 추상 클래스와 인터페이스

다음 강의에서는 **추상 클래스(Abstract Class)**와 **인터페이스(Interface)**에 대해 학습합니다. 😊

LIST