제리의 배움 기록

[Java] 메서드 시그니처 본문

자바

[Java] 메서드 시그니처

제리92 2021. 11. 12. 10:32

메서드 시그니처란?

  • 메서드 정의
  • 자바 컴파일러가 메서드를 구별할 수 있는 기준
  • 메서드 시그니처가 같은 경우, 중복된 메서드 정의로 판단하여 컴파일 오류가 발생

메서드 시그니처 요소

  • 메서드 이름
  • 파라미터 정의(갯수, 순서, 타입)

리턴타입은 왜 메서드 시그니처에 포함되지 않을까?

만약 리턴 타입만 다른 두 메서드가 존재할수 있도록 메서드 시그니처 요소에 리턴타입이 포함된다면,
컴파일러는 어떤 매서드를 호출해야 하는지 판단할 수 없게 됩니다.

이 때문에, 자바 컴파일러가 메서드를 특정할 수 있도록 리턴 타입을 매서드 시그니처에 포함하지 않은 것으로 생각됩니다.

…
System.out.println(testSignature("test"))
//println() 매서드는 overloading으로 다양한 타입을 파라미터로 받을 수 있음 
…
public int testSignature(String str){
  int tNumber=1;
  return tNumber;
}
public String testSignature(String str){
  return str;
}

오버라이딩과 매서드 시그니처

오버라이딩은 상위클래스나 인터페이스에서 정의한 매서드와 다음의 요소가 일치해야 성립합니다.

1) 매서드 시그니처
2) 리턴타입 (상위클래스에 정의된 리턴타입과 동일하거나 하위 타입)
3) 접근제어자

이러한 제약은 자바의 다형성, 느슨한 결합과 관련이 있습니다.

예를들어,

public class Car{    

    public String getName(String name){
        return name;
    }
}

public class Sedan extends Car{

    @override
    public String getName(String name){
        return name+": sedan";
    }
}

public class Suv extends Car{

    @override
    public String getName(String name){
        return name+": suv";
    }
}
...

ArrayList<Car> cars=new ArrayList<>();
Car mainCar=new Car();
Car secondCar=new Sedan();
Car thirdCar=new Suv();

cars.add(mainCar);
cars.add(secondCar);
cars.add(thirdCar);

for(Car car : cars){
    System.out.println(car.getName("jerry"));
}

위 예시에서 Sedan, Suv는 Car을 상속받아 getName 매서드를 재정의했습니다.
하위 클래스에서 정의한 getName 메서드가 메서드 시그니처와 리턴타입까지 같으므로 참조하는 쪽에서는 각 구현체의 내부구현에 신경쓰지 않고 동일하게 취급할 수 있습니다.

 

먄약 메서드 오버라이딩 시 메서드 시그니처만 같아도 되게 허용했다면 어땠을까요?

객체를 참조하는 쪽에서는 추상화에 의존할 수 없고 각각의 세부 객체 타입을 확인하고(instance of) 분기처리하여 그에 맞춘 프로그래밍을 해야했을 겁니다.

이는 강한 결합과 설계의 유연성이 떨어지게 만들고, 오버라이딩의 본질적인 목적인 다형성의 이점을 가져다 주지 못했을 것입니다.

Comments