꾸준한 스터디
article thumbnail

자바가 기본으로 제공하는 애너테이션 중 프로그래머에게 가장 중요한 것은 @Override일 것이다.

@Override는 메서드 선언에만 달 수 있으며, 이 애너테이션이 달렸다는 것은 상위 타입의 메서드를 재정의했음을 뜻한다.

@Override를 일관되게 사용하면 상위 클래스의 메서드를 재정의한다는 가독성과 여러가지 악명 높은 버그들을 예방해준다.

class Parent {
	void parentMethod(){}
}

class Child extends Parent {
	void parentmethod(){} // 오버라이딩하려 했으나 실수로 이름을 잘못적음
}

위의 코드에서처럼 오버라이딩할 때 조상 메서드의 이름을 잘못 써도 컴파일러는 이것이 잘못된 것인지 알지 못한다.

 

오버라이딩할 때는 이처럼 메서드의 이름을 잘못 적는 경우가 많은데, 컴파일러는 그저 새로운 이름의 메서드가 추가된 것으로 인식한다. 게다가 실행 시에도 오류가 발생하지 않고 조상의 메서드가 호출되므로 어디서 잘못되었는지 알아내기 어렵다.

 

class Parent {
	void parentMethod(){}
}

class Child extends Parent {
	@Override
	void parentmethod(){}
}

메서드 앞에 @Override를 붙이면 컴파일러가 같은 이름의 메서드가 조상에 있는지 확인하고 없으면 에러메세지를 출력한다.

 

 

영어 알파벳 2개로 구성된 문자열은 표현하는 Bigram클래스이다.

main 메서드가 실행되고 Set은 중복을 허용하지 않으니 26이 출력될 것 같지만 260이 출력이된다

 

문제의 원인은 작성자는 Object의 equals 메서드를 overriding하려 한 것으로 보이나 매개변수 타입이 Object가 아니어서 overloading이  된 것이다.

Set 클래스 add 메서드 내부에 equals 가 사용되고 Bigram의 equals가 아닌 Object의 equals가 사용되어 == 연산자와 똑같이 객체 식별성(identity)만 확인하고 같은 소문자를 소유한 바이그램 10개 각각이 서로 다른 객체로 인식되고 260을 출력한 것이다.

 

@Override 애너테이션을 붙여줬다면 컴파일 에러로 바로 수정할 수 있었을 것이다.

상위 클래스의 메서드를 재정의하려는 모든 메서드에 @Override 애너테이션을 달자

 

@Override 애너테이션 예외

구체 클래스에서 상위클래스의 추상메서드를 재정의할 때는 굳이 @Override를 달지 않아도 된다.

구체 클래스인데 아직 구현하지 않은 추상 메서드가 남아있다면 컴파일러가 바로 알려준다.

하지만 재정의 메서드 모두 @Override를 일괄로 붙여도 좋아보인다면 달아도 상관 없다.

 

 

@Override는 클래스뿐 아니라 인터페이스의 메서드를 재정의할 떄도 사용할 수 있다.

디폴트 메서드를 지원하기 시작하면서, 인터페이스 메서드를 구현한 메서드에도 @Override를 다는 습관을 들이면 시그니처가 올바른지 재차 확신할 수 있다.

 

구현하려는 인터페이스에 디폴트 메서드가 없음을 안다면 이를 구현한 메서드에서 @Override를 생략해 코드를 조금 더 깔끔히 유지해도 좋다.

 

하지만 추상 클래스나 인터페이스에서는 상위 클래스나 상위 인터페이스의 메서드를 재정의 하는 모든 메서드에 @Override를 다는 것이 좋다.

 

 

 

https://jjingho.tistory.com/88

 

profile

꾸준한 스터디

@StudyRecord

포스팅이 유익하셨다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!