2009-04-03 1 views
40

클래스가 있습니다. 선 그래프를 렌더링하는 LineGraph라고하겠습니다. 하위 클래스가 필요하지만 파생 클래스는 한 곳에서만 사용되며이 클래스를 사용하는 클래스와 결합됩니다. 그래서 내부 클래스를 사용하고 있습니다. ,익명 vs 내부 클래스? - 모범 사례?

익명 내부 클래스 내부 클래스

public class Gui { 
    MyLineGraph graph = new MyLineGraph(); 

    private class MyLineGraph extends LineGraph { 
     // extra functionality here. 
    } 
} 

나는 익명의 내부 클래스가 아닌 팬이 명명 된

public class Gui { 
    LineGraph graph = new LineGraph() { 
     // extra functionality here. 
    }; 
} 

:

나는이 작업을 수행하는 두 가지 방법을 참조 솔직히 나는 단지 그것이 정말로 추악 해 보인다라고 생각하기 때문에. 그러나 한 곳에서만 사용되는 하위 클래스의 경우 명명 된 내부 클래스 과도 함이 있습니까? 허용 된 관행은 무엇입니까?

+5

람다의 누구 : – Matt

답변

9

왜 서브 클래 싱해야합니까? 기존 가상 메서드를 재정의하는 경우 익명의 내부 클래스가 괜찮다고 생각합니다. 추가 기능을 추가하는 경우 명명 된 클래스를 사용합니다. 나는 그것들을 중첩 된 클래스로 만들 것이다. (즉, static 수식어로) - 나는 그들을 쉽게 추론 할 수있다. :)

+0

제 예제는 약간 단순화되었습니다. 실제 코드에서는 5 개의 (비 추상적 인) 메서드를 재정의합니다. –

+0

명명 된 클래스를 만들 가치가있는 것 같습니다. 내 익명의 수업은 작다. –

+1

이 동의했습니다. 정말 간단하다면 익명의 클래스 만 사용합니다. 하나 이상의 작은 함수 정의와 그것을 보통의 내부 클래스 (가능한 경우 정적)로 만들 것입니다. 그렇게 쉽게 읽을 수 있습니다. – Herms

0

나는이 경우에 당신이 그것을 완벽하게 이해했다고 생각한다. , 나는 당신이 정말로이 특별한 이슈와 헤어질 수 있다고 생각합니다. 둘 다 매우 유사하며 둘 중 하나가 작동합니다.

+0

두 가지 옵션이 작동하지만 다른 옵션보다 읽기 쉽고 유지 보수가 쉬운 옵션이 많이 있습니다. 나는 최선의 방법에 대해 의심 할 때 다른 사람들의 의견을 구하는 것이 합리적이라고 생각합니다. –

47

익명 내부 클래스의 장점 중 하나는 아무도 다른 곳에서 사용할 수 없다는 것입니다. 이름이 지정된 내부 클래스를 사용할 수 있습니다 (개인 클래스로 만든 경우에만 클래스를 만든 경우). 작은 구분이지만 내부 클래스가 우연히 다른 곳에서 사용되지 않도록 보호 할 수 있습니다.

또한 익명의 내부 클래스를 사용하면 코드를 읽는 모든 사람에게 "이 클래스는 여기 또는 다른 곳에 사용되지 않습니다."라고 할 수 있습니다. 명명 된 내부 클래스를 보면 누군가가 클래스의 여러 위치에서 사용될 것이라고 생각할 수 있습니다.

그들은 매우 유사하므로 어떤 점도 게임 체인저입니다. 나는 익명의 내부 클래스를 일회용으로 사용하고 내부 클래스를 클래스 내에서 여러 번 사용할 때 명명 된 내부 클래스를 사용하면 명확성을 위해 도움이된다고 생각합니다.

+3

+1 좋은 지적이지만, 클래스는 함수 안에서도 정의 할 수 있습니다. 이는 범위를 제한하며 매우 집중적으로 사용하는 것이 좋습니다. –

+3

다음은 익명의 클래스를 사용하지 않는 이유입니다. :) –

0

나는 이것이 맛의 문제라고 생각합니다. 나는 익명의 클래스를 Functors에 사용하는 것을 선호한다. 그러나 당신의 경우에는 내부 클래스를 사용할 것입니다. 왜냐하면 여러분은 아마 몇 줄의 코드를 포장하는 것일 것입니다. 아마도 단지 방법 이상의 것일 것입니다. 그리고 메소드의 어딘가에 숨겨지기보다는 클래스 안에 넣어서 슈퍼 클래스에 기능을 추가한다는 사실을 강조합니다. 게다가 누가 알겠습니까? 언젠가는 하위 클래스가 필요할 수도 있습니다. 이것은 물론 소프트웨어가 어떻게 발전 할 것인지에 대해 얼마나 많이 알고 있는지에 달려 있습니다. 그 외에 동전을 뒤집어주세요. :)

4

익명 내부 클래스는 Eclipse에서 디버깅하기가 어렵습니다 (사용하는 것). 마우스 오른쪽 버튼으로 변수 값/주사 값을 볼 수 없습니다.

2

일반적으로 익명의 내부 클래스가 사용됩니다. 나는 그것들을 매우 가독성이 있다고 본다. 그러나, 그 클래스의 인스턴스가 serialize 될 필요가 있다면 (심지어 다른 것의 필드이기 때문에), 명명 된 내부 클래스를 사용하는 것이 좋습니다. 바이트 코드의 익명 내부 클래스의 이름은 매우 쉽게 변경 될 수 있으며 이로 인해 직렬화가 중단 될 수 있습니다.익명의 내부 클래스의

36

(다니엘 루에 카운터 포인트)

한 가지 단점은 명명 된 내부 클래스가 사용할 수있는 반면 경우에만 아무도 경우를 생성 한 클래스 (다른 곳에서는 사용할 수 있다는 것입니다 개인 소유). 작은 구분이지만 내부 클래스가 실수로 다른 곳에 다시 생성되지 않도록하는 데 도움이 될 수 있습니다.

또한 익명의 내부 클래스를 사용하면 코드를 읽는 사람이 아무데도 나오지 않는이 클래스를 구문 분석해야하기 때문에 더 힘든 시간을 갖게됩니다. 명명 된 내부 클래스를 사용하면 소스를 더 체계적으로 구성 할 수 있습니다.

완전히 동일한 코드의 익명 내부 클래스가 두 개 (또는 이상)있는 경우를 보았습니다. GUI (특히 여러 컨트롤이 동일한 작업을 수행 할 수있는 곳)에서 이것은 잘릴 수 있습니다 (그리고 학생이 작성한 코드가 아닌 프로덕션 코드로 말하고 있습니다).

가독성 문제는 두 가지로 진행됩니다. 어떤 사람들은 한 번에 무슨 일이 일어나고 있는지, 다른 사람들에게는주의가 산만 해지는 것을 볼 수 있기 때문에 더 나은 익명의 내부 수업을 찾습니다. 그 부분은 개인적인 취향에 달려 있습니다.

인스턴스를 익명의 내부 클래스로 선언하는 경우 인스턴스 변수에 대한 액세스가 필요하지 않은 경우 더 많은 오버 헤드가 발생하므로 낭비 적이지만 문제가 될 때까지는 걱정할 필요가 없습니다).

내 개인적인 선호는 비 익명 클래스를 사용하는 것입니다. 비 익명 클래스는 코드가 나중에 수정 될 때 더 많은 유연성을 허용하기 때문입니다.

+3

이것은 익명의 내부 클래스에 대해 못생긴 것입니다. 당신은 코드를 읽고 있습니다. 갑자기 필드 정의의 중간에 클래스 정의가 있습니다. –

+0

익명 클래스 내부에서 코드를 정렬 할 때 항상 문제가 있습니다. 아무리 노력해도 코드는 여전히 못생긴 것처럼 보입니다. D – janetsmith

+0

동의합니다 - 익명의 내부 클래스가 많으면 코드를 읽기/디버그하기가 어렵습니다. 익명의 내부 클래스를 여러 함수 (YUCK!) 내에서 선언하는 대신, 파일의 섹션을 지정된 내부 클래스, 즉 파일의 맨 아래에 전용하는 것이 훨씬 더 나은 방법이라는 것을 알았습니다. –

3

내부 클래스의 단점은 정적 일 수 없다는 것입니다. 이것은 그것들이 그것을 포함하고있는 외부 클래스에 대한 참조를 보유한다는 것을 의미합니다.

정적이 아닌 내부 클래스가 문제가 될 수 있습니다. 예를 들어 최근에는 내부 클래스가 직렬화되었지만 외부 클래스는 직렬화 할 수 없습니다. 숨겨진 참조는 외래 클래스도 직렬화된다는 것을 의미하지만, 물론 실패했습니다. 그러나 이유를 알아내는 데는 시간이 걸립니다.

내가 일하는 곳에서는 숨겨진 수하물을 적게 들고 더 가볍기 때문에 정적 인 내부 클래스가 코딩 모범 사례 (가능한 경우)에서 권장됩니다.

1

단순한 익명의 클래스에는 문제가 없습니다. 그러나 그것이 몇 줄의 코드 또는 두 가지 이상의 메소드로 구성되어 있다면 내부 클래스가 더 명확합니다. 나는 또한 특정 조건 하에서는 절대로 사용해서는 안된다고 생각한다. 데이터를 반환해야하는 경우 등.

마지막 항목 배열을 사용하여 호출에서 익명의 내부 클래스로 데이터를 다시 전달하는 코드를 보았습니다. anon 클래스의 메서드 내에서 단일 요소가 설정된 다음 메서드가 완료되면이 '결과'가 추출됩니다. 유효하지만 추악한 코드.

7

Do the simplest thing that could possibly work : 익명의 내부 클래스를 사용하십시오.

나중에 더 넓은 범위가 필요하다면이를 지원하는 코드를 리팩토링하십시오.

는 (당신은 변수와 동일한 기능을 수행 할 것 - 가장 구체적인 범위에 이르렀 그것은 다른 소스 자산과 동일한 작업을 수행하는 의미가 있습니다..) 엄지 손가락의

3

내 개인적인 규칙 : 익명의 내부 클래스의 경우 작을 것이고, 익명의 학급에 충실하십시오. 작은 것은 약 20 ~ 30 줄 이하로 정의됩니다. 길어지면 내 의견으로는 읽기가 어려워지기 시작하여 명명 된 내부 클래스로 만듭니다. 익명 내부 클래스가 4000 개 이상인 것을 한번 기억합니다.

2

익명 클래스에는 이름이 없으므로 생성자를 사용할 수 없습니다. 확장하는 클래스의 생성자에있는 변수가 아닌 다른 변수를 전달해야하는 경우에는 (정적 인) 내부 클래스를 사용해야합니다. 이것은 주변의 메소드/코드에서 최종 변수를 사용하여 극복 할 수 있지만 약간 못 생겼습니다 (그리고 Robin이 말한 것으로 이어질 수 있습니다).

1

익명 직업

  • 가 정의 아무것도 static (등 정적 클래스 정적 필드 static 초기화)
  • 필드 Eclipse에서 검사 될 수있을 수
    • 가 같이 사용될 수 없다 유형 이클립스에서 클래스 이름을 사용하여
    • 은 찾을 수 없습니다 (Foo$1 myFoo=new Foo$1(){int x=0;}가 작동하지 않습니다)
    • 캘리포니아를 (Foo$1 검색하는 나를 위해 작동하지 않습니다) nnot

    익명 클래스 수 있지만, {super.foo(finalVariable+this.bar);}

    같은 이니셜이 내부 클래스는 이러한 제한이없는 명명 된,하지만 경우에도 하나의 긴 과정의 중간에 독점적으로 사용되는있는 재사용 할 선언은 다음에 명명 된 클래스로 이동해야합니다. 내가 어떤 추가 필드는 클래스 정의에서 참조 알고

    • : 때문에 제한이 적용되지 않는 경우

      나는 개인적으로 익명의 내부 클래스를 선호합니다.

    • Eclipse는이를 중첩 된 클래스로 쉽게 변환 할 수 있습니다.
    • 사용할 변수를 복사 할 필요가 없습니다. 나는 그 (것)들을 마지막으로 선언하고 그들을 참조 할 수있다. 이것은 많은 매개 변수가있을 때 특히 유용합니다.
    • 상호 작용하는 코드는 서로 가깝습니다.
  • 0

    오늘 제 동료와 함께이 토론을 가졌으며 대중의 의견을 기다리고 있습니다.

    나는 TofuBeer와 합의했다. 코드에 2 행 이상인 코드가있는 경우 아마 일회용이 아니며 언젠가는 다시 사용할 수 있습니다. MVC 패턴을 사용하여 양식을 만드는 경우 페이지에 20 개의 제어 가능한 요소가있을 수 있습니다.보기가 GUI 빌더를 사용하여 작성되었으며 코드가 자동 생성 된 것입니다. 소스를 옵션으로 편집하지 않는다면) 각 요소를 컨트롤러에 공급할 가능성이 높습니다. 컨트롤러에서 내부 클래스를 중첩하여 뷰에서 요구하는 각기 다른 핸들러/수신기 인터페이스를 처리 할 수 ​​있습니다. 이렇게하면 특히 GUI 클래스 이름 (예 : backButtonElement의 경우 backButtonHandler)을 사용하여 핸들러 클래스의 이름을 지정해야한다는 규칙이있는 경우 코드를 실제로 구성 할 수 있습니다. 이것은 우리에게 매우 효과적이었으며 자동 등록 도구를 작성했습니다 (뷰에 컨트롤러를 등록하면 뷰는 요소 이름을 사용하여 내부 클래스를 찾고 각 명명 된 요소의 핸들러에 사용함). 이것은 익명의 클래스에서는 가능하지 않으며 컨트롤러를 훨씬 재활용 할 수 있습니다.

    TLDR : 의심스러운 경우 명명 된 내부 클래스를 작성합니다.언젠가 누군가가 코드를 다시 사용하기를 원한다면 절대 알 수 없을 것입니다. (2 줄이 아니면 '이 코드가 냄새가 나니?'). 잘 조직 된 코드는 특히 프로젝트가 유지 보수중인 경우 장기적으로 훨씬 많은 이점을 제공합니다.

    0

    익명의 내부 클래스를 사용하면 클래스 멤버를 포함하는 클래스의 상태를 변경할 수 없습니다. 그들은 최종 판결을 받아야합니다.