메서드에 제어자 static과 abstract를 함께 못쓰는 이유

CJI0524·2024년 7월 7일
0

Java/Class

목록 보기
1/8

Java를 공부하던 중, 왜 메서드(Method)에 제어자 staticabstract를 함께 사용할 수 없는지에 대해 의문이 생겼다. 이 이유를 서술하기 전에, 먼저 알아야 할 개념들을 살펴보고, 그 이후에 왜 함께 사용할 수 없는지를 설명할 것이다.

1. static 메서드와 instance 메서드의 차이점

우선 Static 메서드는 클래스 레벨의 멤버이고 Instance 메서드는 인스터스 레벨의 멤버이다. 이들의 주된 차이점을 비교하면 다음과 같다.

  • 클래스 레벨 멤버 (Static 변수, Static 메서드)
    클래스 자체에 속하며, 클래스 이름을 통해 직접 호출되고, 모든 인스턴스 간에 공통적으로 공유함.
  • 인스턴스 레벨 멤버 (Instance 변수, Instance 메서드)
    개별 객체에 속하며, 각 객체마다 별도의 값을 가짐.

해당 관계를 그림으로 표현하면 다음과 같다.

  • 클래스 (MyClass)
    staticVariable 및 staticMethod()는 클래스 레벨의 멤버로, 클래스 자체에 속하며 모든 인스턴스 간에 공유된다.

  • 인스턴스 (myObject1, myObject2, myObject3)
    각 인스턴스는 instanceVariable 및 instanceMethod()를 가지며, 이는 인스턴스 레벨의 멤버로 각 객체마다 별도의 값을 가진다.

여기서 핵심은 staticVariable, staticMethod()와 같은 static 멤버들은 인스턴스와는 독립적으로 클래스 자체에 속한다는 사실이다. 그렇기 때문에 인스턴스를 생성하지 않아도 클래스 자체적으로 호출할 수 있는 것이다.

2. static 메서드는 오버라이딩이 가능할까?

Static 메서드의 경우, 부모 클래스를 상속한 자식 클래스에서 오버라이딩하려고 하면, 오버라이딩(Overriding)되지 않고 숨김(Hiding)으로 처리된다.
숨김(Hiding)이란 자식클래스가 부모클래스의 static 메서드와 동일한 이름을 가진 static 메서드를 정의하는 것을 말한다. 이는 자식클래스의 static 메서드가 부모클래스의 메서드를 가리는 것을 의미한다.

용어설명
오버라이딩 (Overriding)• 자식클래스에서 부모클래스의 인스턴스 메서드를 재정의.
• 자식클래스의 메서드가 부모클래스의 메서드를 덮어씀
숨김 (Hiding)• 자식클래스에서 부모클래스의 static 메서드와 동일한 이름과 파라미터 목록을 가진 static 메서드를 정의.
• 부모클래스의 static 메서드는 숨겨지며, 자식클래스의 메서드가 호출됨

다음은 자식클래스에서 부모클래스와 동일한 메서드명의 static 메서드를 정의한 상황을 그림으로 표현한 것이다.

위 그림과 같이 부모 클래스와 자식클래스에서의 staticMethod()는 독립적으로 각각의 클래스 자체에 속한다. 따라서 부모클래스를 상속받았다 할지라도 그것은 자식클래스에서 부모클래스의 staticMethod()에 접근이 가능하게 된 것일 뿐, 부모클래스의 staticMethod()는 여전히 부모클래스에만 속하며 자식클래스에는 속하지 않는다.

이와 같은 이유로 자식클래스에서 부모클래스의 static메서드와 동일한 이름의 static 메서드를 정의할 경우, 부모클래스의 static 메서드는 오버라이딩 되지 않고 숨김으로 처리된다. 각각의 클래스에 독립적으로 존재하니까!


다음은 관련된 예제이다.

✍️ 작성

public class Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Animal");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Animal");
    }
}

public class Cat extends Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Cat");
    }
    @Override
    public void testInstanceMethod() {
        System.out.println("The instance method in Cat");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        Animal myAnimal = myCat;
        Animal.testClassMethod(); // 출력: The static method in Animal
        myAnimal.testInstanceMethod(); // 출력: The instance method in Cat
    }
}

🖥️ 출력

The static method in Animal
The instance method in Cat

Cat 클래스는 Animal 클래스의 인스턴스 메서드를 오버라이딩하고, 정적 메서드를 숨긴다.
main 메서드에서 testClassMethod는 부모클래스의 메서드를 호출한다.
testInstanceMethod는 자식클래스의 메서드를 호출한다.

3. static과 abstract를 함께 사용할 수 없는 이유

위와 같은 내용을 바탕으로 메서드에서 static과 abstract를 함께 사용할수 없는 이유를 설명하자면 두 제어자가 상호 배타적인 특성을 가지고 있기 때문이다.

abstract 제어자는 메서드가 구현되지 않았음을 의미한다. 단지 메서드의 선언부만 제공될 뿐이며 부모클래스의 abstract 메서드는 상속받은 자식클래스가 오버라이딩을 통해 반드시 구현해야 한다. static 메서드는 오버라이딩이 불가능하므로 abstract 메서드는 필연적으로 인스턴스 메서드인 것이다.

그러므로 abstract와 static 제어자는 함께 쓸 수 없다.

4. 해당 게시글 작성에 참고한 글 목록

오라클 Java 문서 : Overriding and Hiding Methods

profile
개발돌이

0개의 댓글