Java 개발에는 일반적으로 C # /. NET보다 더 많은 서브 클래 싱이 포함됩니까?


34

최근에 Android 개발을 살펴보기 시작했습니다. 이것은 Java 소프트웨어 개발의 세계로 다시 돌아 왔습니다. Java로 마지막으로 작업했을 때, 나는 지금 (나는 생각하는 것)만큼 OOP를 이해하지 못했다는 것을 인정할 것이다.

내 경력에서 주로 C #을 사용하면서 상속이 Java 및 C #을 사용하는 방식에 놀라운 차이가 있음을 알았습니다.

C #에서는 대부분의 상황에서 상속을 피할 수있는 것처럼 보였습니다. 당면한 작업은 일반적으로 .NET 프레임 워크 의 구체적인 클래스를 사용하여 수행 할 수 있습니다 .

Java에서 코드 샘플에서 수집하는 것에서 Java 프레임 워크는 개발자가 구현 / 확장 해야하는 많은 인터페이스 또는 추상 클래스를 제공하는 것처럼 보입니다.

이것은 스타일에 비하면 너무 큰 차이 인 것 같습니다. 이것에 대한 추론은 무엇입니까? 나는 이것을 이해할 때까지 깨끗한 Java 코드를 작성하지 않을 것 같습니다.

또한 이것은 Android SDK로만 제한됩니까 아니면 OOP에 대한 Java 전체 접근입니까?

아니면 다른 방법으로

이 두 언어의 디자인이 다른 것보다 상속 사용이 어느 정도입니까 (장려하는 것으로 보입니까)?

언어가 상속을 동일하게 취급하고 내 관찰이 유효하다고 가정하면 언어가 아닌 프레임 워크 / 라이브러리 디자인과 관련이 있음을 의미합니다. 이런 종류의 디자인에 대한 동기는 무엇입니까?


1
사실입니다. Java에 인터페이스가 너무 많습니다. 이 개발자 행동이 특정 언어에 공통적 인 이유를 알고 싶습니다. 나는 이것이 다른 어떤 것보다 Java 프로젝트에서 더 자주 발생하는 것을 본다. 단순한 의견이 아니라 이에 대한 이유가 있어야합니다.
Reactgular

1
@MathewFoscarini 그것은 단지 당신의 의견 입니다. 내가 참여한 Java 프로젝트에서 개발자는 전염병과 같은 상속을 피하는 경향이있었습니다. 여기에 권위있는 것은 없으며 오직 내 의견 만 있습니다. 싶어 설문 조사 ?
gnat

2
Java에서 한 클래스를 다른 클래스에서 파생시킬 필요는 거의 없습니다. 대신, 다형성을 달성하기 위해 인터페이스를 구현하고 합성 된 객체를 구현하고 메서드 호출을 프록시하여 기능을 수행 할 수 있습니다.
DwB

1
@ThinkingMedia 일반적으로 Java는 wiOSS OSS zealots / purists보다 뛰어납니다. 학문적 원칙은 가장 중요한 관심사입니다. .Net 개발자는 작업 수행에 관심이있는 실용 주의자입니다. 가장 깨끗한 코드보다 작업 코드를 중요하게 생각합니다.
Andy

답변:


31

이것은 스타일에 비하면 너무 큰 차이 인 것 같습니다. 이것에 대한 추론은 무엇입니까?

나의 이해는 크게이다 입니다 단순히 문체 결정. 글쎄, 아마도 스타일은 아니지만 언어 / 환경의 관용구입니다. Java 표준 라이브러리 개발자는 한 가지 디자인 지침과 .NET 개발자를 따랐습니다 (Java의 접근 방식이 어떻게 작동하는지 확인할 수 있음).

상속을 장려하거나 설득 할 실제 언어는 거의 없습니다. 두 가지만 관련이 있습니다.

  1. .NET은 너무 많은 제네릭이 아닌 코드가 구현되기 전에 수명 초기에 제네릭을 도입했습니다. 대안은 특수한 것을 타이핑하는 많은 상속입니다.

  2. 더 큰 변화는 .NET이 델리게이트를 지원한다는 것입니다. Java에서는 가장 기본적인 가변 기능을 제공하기 위해 (익명) 상속이 붙어 있습니다. 이로 인해 코드가 델리게이트를 활용하거나 Java에서 코드를 작성하는 데 필요한 어색한 상속 구조를 피하도록 설계되는 방식이 비교적 크게 달라집니다.


3
이 답변은 매우 그럴듯한 설명을 제공한다고 생각합니다. 특히 대리자 대신 익명 상속에 대한 요점. 나는 이것을 많이 관찰했다. 감사.
MetaFight

3
.NET 3.5에 도입 된 익명 유형과 람다 구문 / 표현 트리를 잊지 마십시오. 물론 .NET 4에서 옵트 인 동적 타이핑을 사용하는 것은 당연히 객체 지향이 아닌 혼합 패러다임 언어입니다.
Aaronaught

예, 내 경험에 따르면 (동일한 사람들이 두 언어를 사용하는 혼합 프로젝트 포함) 사람들은 Java를 코딩 할 때 더 많은 수의 더 작은 클래스를 사용하는 경향이 있고 더 적은 수의 더 큰 클래스 (신 클래스에 대한 경향) C #을 사용합니다. 의도적으로 동일한 스타일을 사용하여 동일한 스타일을 프로토 타이핑하면 비슷한 수의 클래스가 생깁니다 (부분 클래스를 사용하면 C #을 사용할 때도 더 많은 코드 파일이 생길 수 있음).
jwenting

6

이들은 특히이 분야에서 매우 다른 언어입니다. 수업이 있다고 가정 해 봅시다. 이 경우 텍스트 상자와 같은 사용자 정의 컨트롤로 만듭니다. 그것을 UIControl이라고 부릅니다. 이제 우리는 이것을 다른 수업에 넣고 싶습니다. 이 예제에서는 UI를 사용하고 있으므로이를 CleverPanel 클래스라고합니다. CleverPanel 인스턴스는 다양한 이유로 UIControl 인스턴스에서 발생하는 일에 대해 알고 싶어합니다. 이것을하는 방법?

C #에서 기본 접근 방식은 다양한 이벤트를 확인하여 각각의 흥미로운 이벤트가 트리거 될 때 실행할 메소드를 설정하는 것입니다. 이벤트가없는 Java에서 일반적인 솔루션은 다양한 "이벤트"처리 방법이있는 객체를 UIControl 메서드에 전달하는 것입니다.

boolean  stillNeedIt =  ... ;
uiControl.whenSomethingHappens( new DoSomething()  {
    public void resized( Rectangle r )  { ... }
    public boolean canICloseNow()  { return !stillNeedIt; }
    public void closed()  { ... }
    ...
} );

지금까지 C #과 Java의 차이점은 심각하지 않습니다. 그러나 C #에는 필요하지 않은 DoSomething 인터페이스가 있습니다. 또한이 인터페이스에는 대부분 필요하지 않은 많은 메소드가 포함될 수 있습니다. C #에서는 해당 이벤트 만 처리하지 않습니다. Java에서는 모든 인터페이스 메소드 DoSomethingAdapter에 대해 널 구현을 제공하는 클래스를 작성합니다. 이제 우리는 DoSomething을 DoSomethingAdapter로 대체하고 깨끗한 컴파일을 위해 메소드를 전혀 작성할 필요가 없습니다. 우리는 프로그램을 올바르게 작동시키는 데 필요한 방법을 재정의합니다. 우리는 인터페이스를 필요로 결국 그래서 그리고 우리는 C #에서 이벤트와 무슨 짓을했는지에 맞게 자바에서 상속을 사용.

이것은 포괄적 인 토론이 아닌 예이지만 C #과는 달리 Java에 왜 많은 상속이 있는지에 대한 기본 사항을 제공합니다.

자, 왜 Java가 이런 식으로 작동합니까? 적응성. whenSomethingHappens가 다른 곳에서 CleverPanel로 완전히 전달되었을 때 전달 된 객체입니다. CleverWindow 객체를 어딘가에 돕기 위해 여러 CleverPanel 인스턴스가 UIControl과 유사한 객체로 전달되어야 할 수도 있습니다. 또는 UIControl 중 하나에 넘겨 수 구성 요소.

또한 어댑터 대신 수천 줄의 코드가있는 DoSomething 구현이있을 수 있습니다. 새로운 인스턴스를 만들어 전달할 수 있습니다. 한 가지 방법을 재정의해야 할 수도 있습니다. Java의 일반적인 트릭은 다음과 같은 메소드를 사용하여 큰 클래스를 갖는 것입니다.

public class BigClass implements DoSomething  {
    ...many long methods...
    protected int getDiameter()  { return 5; }
}

그런 다음 CleverlPanel에서 :

uiControl.whenSomethingHappens( new BigClass()  {
    @Override
    public int getDiameter()  { return UIPanel.currentDiameter; }
} );

오픈 소스 Java 플랫폼은이 작업을 많이 수행하므로 프로그래머가 예제를 따르고 단순히 사용하기 위해 더 많은 노력을 기울이는 경향이 있습니다. 언어의 기본 디자인은 Sun의 프레임 워크 디자인 프레임 워크를 사용 하지 않을 때 기술을 사용하는 Java 프로그래머의 기본이라고 생각합니다 .

Java에서 즉시 클래스를 작성하는 것은 정말 쉽습니다. 익명 또는 명명 된 클래스는 하나의 메소드에 깊이 묻혀있는 하나의 작은 코드 블록에서만 참조하면됩니다. 완전히 새로운 클래스를 만들거나 매우 큰 기존 클래스를 약간 수정하여 만들 수 있습니다. 기존 클래스는 자체 파일에서 최상위 수준이거나 최상위 클래스에 중첩되거나 단일 코드 블록 내에서만 정의 될 수 있습니다. 새 클래스 인스턴스는 모든 생성 객체의 데이터에 대한 전체 액세스 권한을 가질 수 있습니다. 그리고 새 인스턴스는 프로그램 전체에 전달되어 사용되어 인스턴스를 만든 객체를 나타냅니다.

(여기서, Java의 다른 곳에서와 같이 여기에서 상속을 많이 사용하는 것은 단순히 DRY 목적으로 만 사용되며 다른 클래스가 동일한 코드를 재사용 할 수있게합니다. 또한 Java에서 쉽게 상속 할 수 있다는 점에 유의하십시오. )

다시 말하지만 이것은 포괄적 인 토론이 아닙니다. 나는 여기에 표면을 긁적입니다. 그러나 그렇습니다 .Java와 C # 사이에서 상속이 사용되는 방식에는 놀라운 차이가 있습니다. 이런 점에서 그들은 매우 다른 언어입니다. 당신의 상상이 아닙니다.


참고 : 빈 구현으로 가득 찬 추상 클래스를 확장하여 아무것도하지 않는 메소드를 제공하지 않아도됩니다. 이런 식으로 무언가를 수행하는 메소드를 선택적으로 무시할 수 있습니다. 추악하지는 않지만 다른 수준의 상속을 의미합니다.
Peter Lawrey

-2

상속이 Java와 C # 사이에서 처리되는 방식에는 전혀 차이가 없습니다. 실제로 상속이나 컴포지션을 사용하는 것은 디자인 결정이며, Java 또는 C #이 권장하거나 권장하는 것은 아닙니다. 나는 이 기사를 읽는 것을 친절하게 제안 할 것 입니다.

내가 도와줬으면 좋겠다!


5
언어 자체에 대해 이야기하고 있지만 라이브러리와 일반적인 사용법에 대한 질문이라고 생각합니다.
svick

3
그러나 나머지 언어에는 Java의 추가 상속을 장려하는 단점 이 있습니다 . RalphChapin의 답변 참조
Izkata
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.