본문 바로가기
Tutorial/Java

자바의 상속: 기본 개념과 구현

by CLJ 2024. 6. 19.

이 글에서는 자바 상속의 기본 개념부터 구현 방법, 주요 특징, 장단점을 알아보겠습니다.

 

목차

 

상속의 기본 개념과 구현

 

상속이란 ?

상속은 기존 클래스를 확장하여 새로운 클래스를 만드는 방법입니다. 상속은 부모 클래스(슈퍼 클래스)의 특성과 기능을 자식 클래스(서브 클래스)가 물려받아 사용할 수 있게 됩니다. 부모 클래스의 필드와 메소드를 상속받아 사용할 수 있습니다. 

 

구현

상속을 구현하는 기본 문법은 매우 간단합니다. 자식 클래스 정의 시 부모 클래스를 extends 키워드를 사용하여 지정하면 됩니다. 이 키워드는 자식 클래스가 부모 클래스를 상속받는다는 것을 명시합니다. 자식 클래스는 부모 클래스의 모든 공용(public)과 보호된(protected) 멤버를 상속받을 수 있습니다. 자식 클래스는 부모 클래스의 메소드를 재정의 (오버라이드)하여 수정할 수 있습니다. 다음은 기본 상속 문법을 보여주는 예제입니다.

class Parent {
    void display() {
        System.out.println("This is the Parent class.");
    }
}

class Child extends Parent {
    void display() {
        System.out.println("This is the Child class.");
    }
}

 

이 예제에서 Child 클래스는 Parent 클래스를 상속받아 display 메소드를 오버라이드합니다. 이로써 자식 클래스는 부모 클래스의 기능을 확장하거나 수정할 수 있습니다.

 

다음은 좀 더 복잡한 예제로, 부모 클래스와 자식 클래스의 상속 관계를 보여줍니다.

class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    void sound() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void

 main(String[] args) {
        Animal myAnimal = new Animal();
        Animal myDog = new Dog();
        
        myAnimal.sound();  // Outputs: Animal makes a sound
        myDog.sound();     // Outputs: Dog barks
    }
}

 

이 예제에서 Dog 클래스는 Animal 클래스를 상속받아 sound 메소드를 오버라이드합니다. Main 클래스의 main 메소드에서 다형성을 통해 부모 클래스 타입의 변수로 자식 클래스 객체를 참조할 수 있습니다.

 

주요 개념 및 특징

 

메소드 오버라이딩 (Method Overriding)

메소드 오버라이딩은 자식 클래스가 부모 클래스의 메소드를 재정의하는 것을 의미합니다. 이는 자식 클래스에서 부모 클래스의 기본 동작을 변경하고자 할 때 유용합니다. 예를 들어, 모든 동물이 소리를 내는 메소드를 가지고 있다면, 각각의 동물은 이 메소드를 자신의 방식으로 재정의할 수 있습니다.

 

@Override 어노테이션 사용법

@Override 어노테이션은 메소드 오버라이딩을 명시적으로 표시하는 데 사용됩니다. 이는 코드의 가독성을 높이고, 컴파일러가 올바르게 오버라이딩되었는지 확인하는 데 도움을 줍니다. 다음 예제를 통해 @Override 어노테이션의 사용법을 살펴보겠습니다.

class Parent {
    void display() {
        System.out.println("This is the Parent class.");
    }
}

class Child extends Parent {
    @Override
    void display() {
        System.out.println("This is the Child class.");
    }
}

 

이 예제에서 Child 클래스는 Parent 클래스의 display 메소드를 오버라이딩하고, @Override 어노테이션을 사용하여 이를 명시적으로 표시합니다.

 

super 키워드

super 키워드는 자식 클래스에서 부모 클래스의 멤버(필드, 메소드)에 접근하는 데 사용됩니다. 이는 부모 클래스의 메소드를 호출하거나 필드 값을 가져오는 데 유용합니다. 예를 들어, 부모 클래스의 메소드를 오버라이드한 자식 클래스에서, 부모 클래스의 원래 메소드를 호출할 때 super 키워드를 사용할 수 있습니다.

 

부모 클래스 생성자 호출 방법

자식 클래스의 생성자에서 부모 클래스의 생성자를 호출하려면 super 키워드를 사용합니다. 이는 부모 클래스의 초기화 작업을 수행하는 데 필요합니다. 다음 예제는 자식 클래스 생성자에서 부모 클래스 생성자를 호출하는 방법을 보여줍니다:

class Parent {
    Parent() {
        System.out.println("Parent class constructor");
    }
}

class Child extends Parent {
    Child() {
        super();
        System.out.println("Child class constructor");
    }
}

 

이 예제에서 Child 클래스의 생성자는 super()를 사용하여 부모 클래스의 생성자를 호출합니다. 이를 통해 부모 클래스의 초기화 작업이 먼저 수행되고, 그 후에 자식 클래스의 초기화 작업이 수행됩니다.

 

다형성 (Polymorphism)

 

업캐스팅과 다운캐스팅

다형성은 객체 지향 프로그래밍의 핵심 개념 중 하나로, 하나의 객체가 여러 가지 형태를 가질 수 있는 능력을 의미합니다. 업캐스팅은 자식 클래스 객체를 부모 클래스 타입으로 변환하는 것이고, 다운캐스팅은 그 반대입니다. 업캐스팅을 통해 부모 클래스 타입의 변수로 자식 클래스 객체를 참조할 수 있습니다.

 

 


class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    void sound() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myAnimal = new Dog(); // 업캐스팅
        myAnimal.sound(); // Dog barks

        Dog myDog = (Dog) myAnimal; // 다운캐스팅
        myDog.sound(); // Dog barks
    }
}

 

다형성의 장점과 예제

다형성을 활용하면 코드의 유연성과 확장성이 크게 향상됩니다. 예를 들어, 다양한 동물 객체를 다룰 때 다형성을 사용하면 각 동물 객체의 특성에 맞는 메소드를 간편하게 호출할 수 있습니다. 

class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    void sound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    void sound() {
        System.out.println("Cat meows");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myAnimal = new Dog();
        myAnimal.sound(); // Outputs: Dog barks
        
        myAnimal = new Cat();
        myAnimal.sound(); // Outputs: Cat meows
    }
}

 

이 예제에서 Animal 클래스 타입의 변수 myAnimalDog 객체와 Cat 객체를 참조하며, 각각의 sound 메소드를 호출합니다. 이를 통해 다형성의 유연성과 강력함을 확인할 수 있습니다.

 

장점과 단점

 

장점

 

코드 재사용성

상속을 통해 기존 클래스의 코드를 재사용할 수 있습니다. 부모 클래스에 정의된 메소드와 필드를 자식 클래스에서 그대로 사용할 수 있으며, 필요한 경우 이를 확장하거나 수정할 수 있습니다. 이러한 코드 재사용성은 개발 시간을 단축시키고, 중복 코드를 줄여 유지보수를 용이하게 합니다. 예를 들어, 여러 종류의 동물을 나타내는 클래스들이 공통적인 특성을 공유할 때, 이들을 상속 구조로 설계하면 코드 중복을 피할 수 있습니다.

 

유지보수성 향상

상속을 사용하면 공통 기능을 부모 클래스에 집중시킬 수 있어 유지보수성이 향상됩니다. 부모 클래스의 코드를 수정하면 이를 상속받는 모든 자식 클래스에 자동으로 반영되므로, 일관된 코드를 유지하는 데 도움이 됩니다. 이는 특히 대규모 프로젝트에서 변경 사항을 관리하는 데 유리합니다. 예를 들어, 사용자 인터페이스 클래스에서 공통적인 레이아웃 변경이 필요할 때, 부모 클래스에서 한 번의 수정으로 모든 자식 클래스에 동일하게 적용될 수 있습니다.

 

단점

 

클래스 간 결합도 증가

상속을 사용하면 자식 클래스가 부모 클래스에 강하게 결합됩니다. 부모 클래스의 변경이 자식 클래스에 영향을 미칠 수 있어, 예상치 못한 오류가 발생할 가능성이 높아집니다. 이는 유지보수성을 저해할 수 있으며, 클래스 구조의 유연성을 감소시킵니다. 예를 들어, 부모 클래스의 메소드 시그니처를 변경하면 이를 상속받은 모든 자식 클래스에서 해당 메소드를 수정해야 할 수도 있습니다.

 

다중 상속의 문제와 인터페이스로 해결하는 방법

자바는 다중 상속을 지원하지 않습니다. 이는 한 클래스가 두 개 이상의 부모 클래스를 상속받을 수 없다는 것을 의미합니다. 다중 상속은 메소드 충돌 등의 문제를 일으킬 수 있어, 자바에서는 이를 인터페이스를 통해 해결합니다. 인터페이스를 사용하면 클래스는 여러 인터페이스를 구현할 수 있어 다중 상속의 유연성을 제공하면서도 복잡성을 줄일 수 있습니다.

interface Animal {
    void eat();
}

interface Pet {
    void play();
}

class Dog implements Animal, Pet {
    @Override
    public void eat() {
        System.out.println("Dog eats");
    }

    @Override
    public void

 play() {
        System.out.println("Dog plays");
    }
}

 

이 예제에서 Dog 클래스는 Animal 인터페이스와 Pet 인터페이스를 구현하여, 두 인터페이스의 메소드를 모두 정의합니다. 이를 통해 다중 상속의 문제를 해결하면서도 필요한 기능을 모두 포함할 수 있습니다.

 

결론

 

자바 상속은 객체 지향 프로그래밍의 강력한 도구로, 코드 재사용성과 유지보수성을 크게 향상시킵니다. 상속의 기본 개념을 이해하고, 이를 적절하게 활용하면 보다 효율적이고 유연한 프로그램을 개발할 수 있습니다. 하지만 상속을 남용하면 클래스 간 결합도가 증가할 수 있으므로, 인터페이스와 같은 다른 객체 지향 원칙도 함께 고려하여 설계하는 것이 중요합니다. 

 

2024.05.21 - [Java] - 자바(Java) 추상 클래스(Abstract class)의 정의와 목적, 사용법과 예시, 주의사항

 

자바(Java) 추상 클래스(Abstract class)의 정의와 목적, 사용법과 예시, 주의사항

자바 프로그래밍 언어에서 추상클래스는 객체 지향 프로그래밍의 핵심 개념 중 하나입니다. 이는 클래스 계층구조에서 상위 클래스의 역할을 하며, 다른 클래스들이 상속받아 구체화할 수 있는

it-learner.tistory.com

 

 

2024.05.21 - [Java] - 자바(Java) 인터페이스(Interface) 개념, 사용법, 장점, 실용 예제

 

자바(Java) 인터페이스(Interface) 개념, 사용법, 장점, 실용 예제

자바 프로그래밍에서 인터페이스는 매우 중요하기 때문에 반드시 기억해야 하는 개념인데요. 인터페이스는 객체지향 프로그래밍의 핵심 원칙인 다형성(polymorphism)을 구현하는 데 큰 역할을 합

it-learner.tistory.com