Java 자바의 기초 (상속, super, 메소드 오버로딩 & 오버라이딩)

개발일지

객체 지향 프로그래밍에서 중요한 주제 중 하나인 상속에 대해 학습하였습니다. 기본 이해가 중요하다고 생각하여 기본 개념에 집중하면서 코드를 작성하며 상속의 과정을 익히는데 많은 시간을 투자했습니다. 이번 글에서는 상속, super, 메소드 오버로딩, 메소드 오버라이딩에 대한 학습 내용을 간략하게 정리해보겠습니다.

상속

자바에서 상속은 객체 지향 프로그래밍의 핵심 개념 중 하나로, 기존 클래스의 특성(멤버 변수 및 메소드)을 새로운 클래스에서 재사용하고 확장하는 데 사용됩니다.

기본 구문

자바에서 상속은 extends 키워드를 사용하여 특정 클래스를 상속받는 형태로 이루어집니다. 상속을 받는 클래스는 “자식 클래스”이고, 상속을 제공하는 클래스는 “부모 클래스”입니다.

Java
class 부모클래스 {
    // 부모 클래스의 멤버 변수 및 메소드들
}

class 자식클래스 extends 부모클래스 {
    // 자식 클래스의 추가적인 멤버 변수 및 메소드들
}
Java

메소드 오버라이딩

자식 클래스에서 부모 클래스의 메소드를 동일한 시그니처로 다시 정의하는 것을 “메소드 오버라이딩”이라고 합니다. 이를 통해 자식 클래스는 부모 클래스의 메소드를 재정의하거나 확장할 수 있습니다.

Java
class 부모클래스 {
    void 메소드() {
        System.out.println("부모 메소드");
    }
}

class 자식클래스 extends 부모클래스 {
    void 메소드() {
        System.out.println("자식 메소드");
    }
}
Java

super 키워드

자식 클래스에서 부모 클래스의 메소드를 호출할 때 super 키워드를 사용할 수 있습니다.

Java
class 자식클래스 extends 부모클래스 {
    void 메소드() {
        super.메소드(); // 부모 클래스의 메소드 호출
        System.out.println("자식 메소드");
    }
}
Java

다형성(Polymorphism)

상속을 통해 다형성을 구현할 수 있습니다. 부모 클래스 타입의 변수에 자식 클래스의 객체를 할당할 수 있고, 이를 통해 동일한 메소드 호출로 다양한 동작을 구현할 수 있습니다.

부모클래스 객체 = new 자식클래스();

접근 제어자

상속 관계에서는 부모 클래스의 멤버 변수 및 메소드의 접근 제어자에 주의해야 합니다. 부모 클래스에서 protected나 public으로 선언된 멤버들은 자식 클래스에서 접근할 수 있지만, private으로 선언된 멤버들은 직접 접근할 수 없습니다.

super

super 키워드는 자바에서 상속 관계에서 부모 클래스의 멤버에 접근하는 데 사용되는 특별한 키워드입니다. super를 통해 부모 클래스의 생성자, 멤버 변수, 메소드에 접근할 수 있습니다.

부모 클래스의 메소드 호출

super를 사용하여 자식 클래스에서 부모 클래스의 메소드를 호출할 수 있습니다. 이는 메소드 오버라이딩 등의 상황에서 부모 클래스의 동작을 유지하면서 추가적인 동작을 수행할 때 유용합니다.

Java
class 부모클래스 {
    void 일반메소드() {
        System.out.println("부모 클래스의 일반 메소드");
    }
}

class 자식클래스 extends 부모클래스 {
    void 일반메소드() {
        super.일반메소드(); // 부모 클래스의 메소드 호출
        System.out.println("자식 클래스의 일반 메소드");
    }
}
Java

부모 클래스의 멤버 변수 접근

super를 사용하여 자식 클래스에서 부모 클래스의 멤버 변수에 접근할 수 있습니다. 이는 자식 클래스에서 동일한 이름의 멤버 변수가 선언되었을 때, 부모 클래스의 멤버 변수에 명시적으로 접근하고자 할 때 사용됩니다.

Java
class 부모클래스 {
    String 공통변수 = "부모 클래스의 변수";
}

class 자식클래스 extends 부모클래스 {
    String 공통변수 = "자식 클래스의 변수";

    void 출력() {
        System.out.println(super.공통변수); // 부모 클래스의 변수 출력
        System.out.println(this.공통변수);    // 자식 클래스의 변수 출력
    }
}
Java

부모 클래스의 생성자 호출

super는 부모 클래스의 생성자를 호출하는데에도 사용됩니다. 자식 클래스에서 생성자를 정의할 때, 명시적으로 super()를 호출하여 부모 클래스의 기본 생성자를 실행하거나, 특정한 매개변수를 가진 부모 클래스의 생성자를 호출할 수 있습니다.

Java
class 부모클래스 {
    부모클래스() {
        System.out.println("부모 클래스의 기본 생성자");
    }

    부모클래스(String message) {
        System.out.println("부모 클래스의 생성자: " + message);
    }
}

class 자식클래스 extends 부모클래스 {
    자식클래스() {
        super(); // 부모 클래스의 기본 생성자 호출
        System.out.println("자식 클래스의 기본 생성자");
    }

    자식클래스(String message) {
        super(message); // 부모 클래스의 특정 생성자 호출
        System.out.println("자식 클래스의 생성자: " + message);
    }
}
Java
  • super 키워드는 자식 클래스에서 부모 클래스의 멤버에 접근하거나, 부모 클래스의 생성자를 호출하는 등 상속 관계에서 부모 클래스와의 상호 작용을 할 때 사용됩니다.

메소드 오버로딩

자바에서 메소드 오버로딩은 같은 이름의 메소드를 여러 개 정의하는 것을 말합니다. 이 메소드들은 서로 다른 매개변수 목록을 가져야 합니다. 즉, 메소드의 시그니처(매개변수의 타입, 개수, 순서)가 서로 달라야 합니다.

메소드 오버로딩은 다형성을 구현하는 한 가지 방법으로, 동일한 기능을 수행하는 여러 메소드를 하나의 이름으로 그룹화할 수 있습니다. 다음은 메소드 오버로딩의 예시입니다:

Java
public class Calculator {
    // 정수형 두 개를 더하는 메소드
    public int add(int a, int b) {
        return a + b;
    }

    // 문자열을 이어붙이는 메소드
    public String add(String a, String b) {
        return a + b;
    }
}
Java
  • 이 예제에서는 add라는 메소드를 두 번 정의하고 있습니다.
  • 각각의 메소드는 다른 매개변수 타입을 가지고 있습니다.
  • 이렇게 하면 다양한 타입의 데이터를 다룰 수 있으며, 클라이언트 코드에서는 동일한 이름의 메소드를 호출함으로써 간편하게 사용할 수 있습니다.

💡메소드 오버로딩은 다음 규칙을 따라야 합니다.

  1. 메소드 이름은 동일해야 합니다.
  2. 매개변수의 개수나 타입, 순서가 달라야 합니다.
  3. 반환 타입은 메소드 오버로딩에 영향을 주지 않습니다.

메소드 오버라이딩

메소드 오버라이딩(Override)은 자바에서 상속 관계에 있는 부모 클래스의 메소드를 자식 클래스에서 새롭게 정의하는 것을 의미합니다. 오버라이딩을 통해 자식 클래스는 부모 클래스의 메소드를 재정의하여 자신의 필요에 맞게 구현할 수 있습니다.

메소드 오버라이딩의 조건

  1. 메소드 시그니처가 동일해야 합니다.
    • 메소드의 이름, 반환 타입, 매개변수 목록이 부모 클래스의 메소드와 동일해야 합니다.
  2. 접근 제어자는 확장되거나 동일해야 합니다.
    • 부모 클래스의 메소드가 public이면 자식 클래스에서는 public 또는 protected로 오버라이딩할 수 있습니다. 반면에 부모 클래스의 메소드가 protected이면 자식 클래스에서는 protected로만 오버라이딩이 가능합니다.
  3. 예외를 던지는 부분은 축소할 수 없습니다.
    • 자식 클래스에서 오버라이딩하는 메소드에서 던지는 예외는 부모 클래스에서 던지는 예외의 하위 클래스이거나 동일해야 합니다.

메소드 오버라이딩의 예시

Java
class 부모클래스 {
    void 메소드명() {
        System.out.println("부모 클래스의 메소드");
    }
}

class 자식클래스 extends 부모클래스 {
    @Override // 어노테이션을 통해 오버라이딩임을 명시
    void 메소드명() {
        System.out.println("자식 클래스에서 오버라이딩한 메소드");
    }
}
Java
  • 위의 예시에서 자식클래스에서 부모클래스의 메소드명() 메소드를 오버라이딩했습니다.
  • @Override 어노테이션은 컴파일러에게 해당 메소드가 오버라이딩임을 명시하는 역할을 합니다.

메소드 오버라이딩의 활용

Java
public class Main {
    public static void main(String[] args) {
        부모클래스 부모객체 = new 부모클래스();
        부모객체.메소드명(); // 부모 클래스의 메소드 호출

        자식클래스 자식객체 = new 자식클래스();
        자식객체.메소드명(); // 자식 클래스에서 오버라이딩한 메소드 호출

        // 다형성을 이용하여 부모 클래스의 참조 변수로 자식 객체를 참조 가능
        부모클래스 다형성객체 = new 자식클래스();
        다형성객체.메소드명(); // 자식 클래스에서 오버라이딩한 메소드 호출
    }
}
Java
  • 위의 예시에서 부모클래스와 자식클래스에서 오버라이딩한 메소드를 호출하는 예시를 보여줍니다.
  • 다형성을 이용하여 부모 클래스의 참조 변수로 자식 객체를 참조할 경우, 실제로 생성된 객체의 타입에 따라 오버라이딩된 메소드가 호출됩니다.

메소드 오버라이딩은 자식 클래스에서 부모 클래스의 메소드를 재정의하여 유연하고 다양한 동작을 할 수 있도록 해주는 중요한 객체 지향 프로그래밍의 개념 중 하나입니다.

메서드 오버로딩 Vs 메서드 오버라이딩

자바에서 메서드 오버로딩(Overloading)과 오버라이딩(Overriding)은 둘 다 다형성을 구현하는 방법 중 하나로 사용되지만, 각각의 특징과 목적이 다릅니다.

메서드 오버로딩 (Method Overloading)

같은 클래스 내에서 메서드 이름은 같지만 매개변수의 타입, 개수, 또는 순서가 다른 여러 메서드를 정의하는 것을 메서드 오버로딩이라고 합니다.

💡특징:

  • 메서드 시그니처가 달라야 합니다.
  • 반환 타입은 메서드 오버로딩에 영향을 주지 않습니다.
  • 컴파일러가 메서드 호출 시 전달된 인자의 타입에 따라 호출할 메서드를 결정합니다.

💡예시:

Java
class 계산기 {
    int 더하기(int a, int b) {
        return a + b;
    }

    double 더하기(double a, double b) {
        return a + b;
    }
}
Java

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

부모 클래스에서 정의된 메서드를 자식 클래스에서 동일한 시그니처로 다시 정의하는 것을 메서드 오버라이딩이라고 합니다.

💡특징:

  • 메서드 시그니처가 일치해야 합니다(이름, 매개변수, 반환 타입).
  • @Override 어노테이션을 사용하여 오버라이딩이 제대로 이루어졌는지 확인할 수 있습니다.
  • 메서드 호출 시 객체의 실제 타입에 따라 오버라이딩된 메서드가 호출됩니다.

💡예시:

Java
class 부모클래스 {
    void 메서드() {
        System.out.println("부모 클래스의 메서드");
    }
}

class 자식클래스 extends 부모클래스 {
    @Override
    void 메서드() {
        System.out.println("자식 클래스에서 재정의한 메서드");
    }
}
Java

차이점 요약

  • 메서드 오버로딩
    • 한 클래스 내에서 동일한 이름의 메서드를 여러 개 정의.
    • 매개변수의 타입, 개수, 순서가 달라야 함.
  • 메서드 오버라이딩
    • 상속 관계에서 부모 클래스의 메서드를 자식 클래스에서 재정의.
    • 메서드 시그니처가 일치해야 함.
    • @Override 어노테이션 사용 가능.

마무리

상속, super, 메소드 오버로딩, 메소드 오버라이딩에 대한 내용을 학습했습니다.

상속을 통해 부모 클래스의 특성을 자식 클래스에서 활용하고 확장하는 방법을 학습했습니다. 또한, 메소드 오버로딩과 메소드 오버라이딩을 사용하여 동일한 이름의 메소드를 다양한 매개변수와 구현으로 정의하는 방법을 익혔습니다.

특히, super 키워드를 사용하여 부모 클래스의 멤버에 접근하거나 부모 클래스의 생성자를 호출하는 방법을 이해했습니다. 이는 상속 관계에서 자식 클래스와 부모 클래스 간의 원활한 상호 작용을 도와줍니다.

메소드 오버로딩과 오버라이딩은 다형성을 구현하는 데에 중요한 역할을 합니다. 같은 이름의 메소드를 다양한 매개변수로 정의하거나, 부모 클래스의 메소드를 자식 클래스에서 재정의하여 유연하고 다양한 동작을 구현할 수 있게 됩니다.

이러한 학습을 통해 객체 지향 프로그래밍의 핵심 개념을 이해하고, 코드를 더 효과적으로 작성할 수 있는 능력을 키워 나가는 중입니다. 앞으로도 새로운 주제에 대한 학습과 경험을 통해 성장하고 발전해 나가려 합니다.🚀

Leave a Comment