2010-01-30 2 views
9

클래스의 개별 메소드를 만들기위한 동기가 무엇인지 알고 있습니까? sealed/final하지만 클래스 서브에서 상속을 완전히 금지하는 목적은 무엇입니까? 어떤 메소드의 오버라이드를 허용하면 나쁜 일이 발생할 수 있지만, 클래스의 상속을 순수하게 기존의 동작을 재정의하지 않고 동작을 추가하는 것이 나쁜 일일 수 있다는 것을 나는 볼 수 없다. 만약 당신이 정말로 당신의 클래스에서 무엇이든지 오버 라이딩하는 것을 허락하고 싶지 않다면, 모든 메소드를 final로 만들지 말고 행동을 추가 할 목적으로 상속을 허용하는 것이 어떻겠습니까?왜 전체 수업을 봉인/마지막으로 하시겠습니까?

+0

java.util.UUID의 경우 나는 좌절감을 가질 수 없다는 것을 발견했다. –

답변

3

조직/소프트웨어 개발 팀은 특정 코딩 표준을 시행하고자 할 수 있습니다. 예를 들어, 가독성을 높이기 위해서 (때문에), 클래스 Y의 속성 X를 Z 메소드로 변경하는 것만으로 변경할 수 있습니다. 클래스가 final이 아닌 경우 일부 개발자는 클래스 Y를 확장하고 메소드 W를 추가하여 X를 다른 방식으로 수정할 수 있으며 작성된 코드를 이해할 때 혼란과 지연을 초래할 수 있습니다.

+0

속성 X를 비공개로 설정하지 않았습니까? – Dalius

+1

@Dalius X private 인 경우에도 Y 객체의 Z에 대한 직접 호출 만 X에 영향을주는 것이 바람직 할 수 있습니다. 클래스 W가 Z를 오버라이드하는 경우 W 객체의 Z를 호출하여 X를 변경할 수 있습니다. 이는 Y 객체로부터 Z 메소드 호출을 통해서만 X를 변경하려는 초기의 욕구를 깨뜨린다. 나는 개인적으로 그런 상황을 본 적이 없지만 일어날 수 있다고 생각한다. –

4

은 "문자열 자바에서 최종 왜"질문이에 대한 몇 가지 좋은 토론이 있습니다 Why is String class declared final in Java?

이 경우에 기본 요약, 문자열은 불변이며,이 서브 클래스화할 수 있다면, 서브 클래스는 수도 그것을 변경할 수있게하십시오.

2

이런 식으로 생각해보십시오 : 지난 3 개월 동안 다른 프레임 워크가 사용할 프레임 워크의 기본 클래스에서 작업하고 프레임 워크의 전체 일관성은이 클래스에 작성된 코드를 기반으로합니다. 이 클래스는 프레임 워크의 버그, 오류 및 오작동을 유발할 수 있습니다. 위대한 프로그래머가 확장하여 메서드 중 하나를 재정의하지 못하게하려면 어떻게해야합니까?

이 외에도 Java의 java.lang.String 클래스와 같이 변경할 수없는 클래스가 있으며 확장하여 동작을 변경하면 큰 혼란을 야기 할 수 있습니다!

마지막으로 클래스 또는 메서드를 final로 설정하면 성능이 향상되지만 결코 테스트하지 않았고 지구상에서 클래스/메서드를 final로 만드는 이유가 거의 없습니다. 프로그램 내 다른 것들을 처리하는 데 필요한 시간에 비해 0입니다.

+0

1. 문제는 하위 클래스가 동작을 추가하도록 허용하는 것입니다. 내가 왜 당신이 무시 무시하고 싶지 이해합니다. 2. 수업이 3 개월이 걸릴 경우, 너무 많이 할 것입니다. – dsimcha

+0

문학적으로 3 개월을 사용하지 마십시오.이 아이디어는 연약한 맥락에서 중요한 수업이었고, 다른 모든 반에서는 특정 행동에 복종 할 것으로 기대했습니다. –

3

보다 일반적으로 클래스는 그것이 작동하게하는 불변성을 보존하기 위해 최종적으로 만들 수 있습니다. Joshua Bloch의 "Effective Java"를 통해이 문제와 관련 문제에 대한 훌륭한 토론을 적극 권장합니다.

0

나는 그것이 달려 있다고 생각합니다.

내부 응용 프로그램이있는 경우 기본적으로 클래스 수준에서 최종본을 사용하지 않습니다. 코드가 너무 혼란스러워집니다. 경우에 따라 최종 수정 자도 실제로 리팩토링하려는 경우 매우 성가시다 (programming by difference 용어 참조). 어떤 경우에는 리팩토링을 시도 할 때 'default-final-mania'가 큰 문제가되었습니다.

반면에 코드가 좀 더 확장 구동 인 api/프레임 워크를 디자인하면 '좀 더 적극적으로'클래스의 final을 사용하게됩니다. 여기서 잘못된 확장은 큰 문제가 될 수 있고 'final'수정자는 그러한 프로그래밍 실수를 피하는 안전한 방법입니다.

하지만 저는 많은 사람들처럼 기본적으로 '최종'이라고 말하기를 반대합니다. 장점으로는 종종 더 많은 단점이 있습니다. 나에게는 기본값이 '합리적이고보다 일반적인 설정'이어야합니다.

0

내가 아는 한, 그것은 불변성을 유지하는 것입니다.

비슷한 상황에서 예를 들어 속성을 공개 할 수는 있지만 클라이언트가 유지 관리하려는 일부 속성을 위반하여 직접 변경할 수 있기 때문에 값을 제어 할 수 없습니다. 따라서 일부 불변량을 유지하기 위해 클라이언트가 일부 (실제로는) 필드에 직접 액세스하는 것을 금지하는 것과 같은 방법으로 클래스/메소드를 최종적으로 변경하여 일부 불변성을 유지합니다.

내가보기에 일반적인 예는 클래스가 최종이 아니라면 깨질 수있는 불변성입니다.

사용자가 클래스를 확장하여 자신의 시스템에서만 사용하고 다른 모든 것과 격리 된 자신 만의 "엉망"으로 생활 할 때 문제는 실제로 발생하지 않습니다. 실제 문제는 클래스/메소드/속성/객체/...가 분리되어 존재하지 않는다는 사실과 관련이 있습니다.

어떤 목표를 향해 공존하는 CC1 컬렉션이 있고 CC1_A 클래스 중 하나는 변경 불가능한 개체 (또는 원하는 다른 불변의 개체) 만 "생산해야"한다고 가정 해보십시오. 그런 다음 CC1_A를 확장하여 CC2_AX (두 번째 클래스 컬렉션에서 확장 A)를 만듭니다. 지금 할 수있는 것은 CC1_A가 필요한 CC2_AX를 통과하는 CC1 물건을 사용하는 것입니다. 그러나 CC1은 CC1_A 객체가 불변이라고 가정하고 작성되었지만 CC2_AX 객체는 아닙니다 (예를 들어 단순한 것이 아니라고 가정). 이로 인해 프로그램에 심각한 문제가 발생할 수 있습니다. 이러한 문제는 수업 내에서도 발생할 수 있습니다. 예를 들어, CC1_A의 메소드는 CC1_A 객체가 불변이라고 가정 할 것이므로 CC2_AX가 불변 속성을 깨기 때문에 CC1_A에서 나온 CC2_AX의 메소드는 잠재적으로 실패 할 수 있습니다.

우리 시스템에는 오늘날 많은 클래스가 있으며 우리가하는 일은 절대적으로 많이 발생합니다. 그래서 우리는 항상 우리가 유지하고자하는 불변량을 생각하지 않습니다. 이것은 일을 더 쉽게하지 않습니다. 정렬 방법은 안정적이어야

  • : 그런데

    는 다른 불변는 같은 것들을 포함한다.
  • 이러한 > 방법은 > 알고리즘과 같은 <을 사용합니다.
  • < 클래스 >리스트 구현은 이라고 표시된 <과 같이 단순한 링크 된 목록 구현을 사용해야합니다.

계속됩니다. 어떤 클래스는보다 강력한 불변량 (예 : 특정 알고리즘의 사용)을 유지하기 때문에 유용하며, 확장은 사람들이 그러한 종류의 것을 쉽게 깨뜨릴 수있게합니다. 그리고 이것이 모두 문제인 이유는 고립되어 살지 않는 이런 것들과 관련이 있습니다.

관련 문제