.NET의 모든 클래스가 전역 적으로 Object 클래스에서 상속되는 이유는 무엇입니까?


16

프레임 워크에 대한 "글로벌 루트 클래스"접근 방식을 제공하는 이점은 매우 흥미 롭습니다. 간단히 말해서 .NET 프레임 워크의 결과는 모든 클래스에 적합한 일반 기능 을 가진 하나의 루트 객체 클래스 를 갖도록 설계되었습니다 .

오늘날 우리는 내부 사용을위한 새로운 프레임 워크 (SAP 플랫폼 하의 프레임 워크)를 설계하고 있으며, 둘 다 두 개의 캠프로 나뉘 었습니다.

나는 "글로벌 루트"캠프에 있습니다. 그리고 그러한 접근 방식으로 인해 유연성과 개발 비용이 절감되는 이유는 더 이상 일반적인 기능을 개발하지 않을 것입니다.

따라서 .NET 건축가가 그러한 방식으로 프레임 워크를 설계 해야하는 이유를 알고 싶습니다.


6
.NET Framework는 일반화 된 소프트웨어 개발 환경의 일부입니다. 자신과 같이보다 구체적인 프레임 워크에는 "루트"객체가 필요하지 않을 수 있습니다. 루트가있다 object이 같은 모든 객체에서 몇 가지 기본적인 기능을 제공하기 때문에 일부에서 .NET 프레임 워크 ToString()GetHashCode()
로버트 하비

10
"저는 왜 .NET 설계자들이 그런 방식으로 프레임 워크를 설계해야하는지 이유를 알고 매우 흥미 롭습니다." 그 이유는 다음과 같은 세 가지 이유가 있습니다. 1. Java가 그렇게했고, 2. Java가 그렇게했으며, 3. Java가 그렇게했습니다.
dasblinkenlight

2
@vcsjones : 및 예를 들어 Java는 이미 wait()/ notify()/ notifyAll()및로 오염되었습니다 clone().
Joachim Sauer

3
트윗 담아 가기 자바는 그렇게하지 않았다.
단테

2
@dasblinkenlight : 참고로, Java는 현재 람다, LINQ 함수 등을 사용하여 C #을 복사하는 하나입니다.
user541686

답변:


18

가장 시급한 원인 Object은 컨테이너 (제네릭보다 우선 )인데 C 스타일 "필요한 모든 것에 대해 다시 작성"하는 대신 무언가를 포함 할 수 있습니다. 물론 모든 것이 특정 클래스에서 물려받은 다음 유형 안전의 모든 스펙을 완전히 잃기 위해이 사실을 남용해야한다는 생각은 너무 끔찍하여 제네릭없이 언어를 배송하는 것에 대한 거대한 경고 표시가되어야합니다. 이는 Object새로운 코드에는 완전히 중복됩니다.


6
이것이 정답입니다. 일반적인 지원 부족이 유일한 이유였습니다. 일반적인 방법이 일반적 일 필요는 없기 때문에 다른 "공통 방법"인수는 실제 인수가 아닙니다. 예 : 1) ToString : 대부분의 경우 남용됩니다. 2) GetHashCode : 프로그램의 기능에 따라 대부분의 클래스에는이 메소드가 필요하지 않습니다. 3) GetType : 인스턴스 메소드 일 필요는 없음
Codism

2
.NET은 모든 것이 특정 클래스에서 상속되어야한다는 생각을 "용해"함으로써 "안전한 유형의 모든 스펙을 완전히 잃어 버리는"방법은 무엇입니까? C ++ Object로 작성할 수없는 shitcode가 void *있습니까?
Carson63000 5

3
내가 void*더 좋다고 누가 말했 습니까? 그렇지 않습니다. 있다면. 그건 더 악화 .
DeadMG

void*C에서 모든 암시 적 포인터 캐스트가 더 나쁘지만 C ++ 은이 점에서 더 엄격합니다. 최소한 명시 적으로 캐스팅해야합니다.
Tamás Szelei

2
@fish : 용어 퀴즈 : C에는 "암시 적 캐스트"와 같은 것은 없습니다. 캐스트는 변환을 지정하는 명시 적 연산자입니다. "암시 적 포인터 변환 "을 의미 합니다.
키이스 톰슨

11

나는 상속 말하는 일단 에릭 Lippert의 기억 System.Object클래스 것은 '고객을위한 최고의 가치'를 제공했다. [편집 : 네, 그는 여기에서 말했습니다 ] :

... 공통 기본 유형이 필요 하지 않습니다 . 이 선택은 필요하지 않았습니다. 고객에게 최고의 가치를 제공하고자하는 바람에 이루어졌습니다.

유형 시스템 또는 그 문제에 대한 다른 것을 설계 할 때 때때로 결정 포인트에 도달합니다. X 또는 X를 결정해야합니다. 누적은 공통 기본 유형이없는 순 이익보다 큽니다. 따라서 우리는 공통 기본 유형을 선택합니다.

꽤 모호한 대답입니다. 보다 구체적인 답변을 원하면보다 구체적인 질문을하십시오.

System.Object수업 에서 얻은 모든 것을 갖는 것은 내가 존경하게 된 신뢰성과 유용성을 제공합니다. 모든 객체는 유형 ( GetType)을 가지며 CLR의 종료 방법 ( Finalize)과 일치 GetHashCode하며 컬렉션을 처리 할 때 사용할 수 있음을 알고 있습니다 .


2
이것은 결함이 있습니다. 필요하지 않습니다. GetType단순히 typeof기능을 대체 하도록 확장 할 수 있습니다 . 에 관해서는 Finalize, 다음 실제로, 많은 유형이 완전히 전혀 마무리가되지 않고 의미있는 Finalize 메서드를 가지고 있지 않습니다. 또한 많은 유형이 해시 가능하거나 문자열 특히 내부 유형으로 변환 할 수 없으며 그러한 목적으로 사용되지 않으며 공개적으로 사용되지 않습니다. 이러한 모든 유형은 인터페이스가 불필요하게 오염되었습니다.
DeadMG

5
아니, 그것은 결함이 아니에요 - 난 당신이 사용하는 것이라고 주장하지 GetType, Finalize또는 GetHashCode모든을 위해 System.Object. 나는 당신이 그들을 원한다면 거기에 있다고 말했다. "그들의 인터페이스가 불필요하게 오염되었습니다"에 관해서는, "고객을위한 최상의 가치"라는 원래 elippert 인용문을 언급 할 것입니다. 분명히 .NET 팀은 트레이드 오프를 기꺼이 처리했습니다.
gws2

필요하지 않은 경우 인터페이스 오염입니다. "원하는 경우"는 방법을 포함시키는 좋은 이유가 아닙니다. 당신이 그것을 필요로하고 소비자가 그것을 호출하기 때문에 거기에 있어야 합니다 . 그렇지 않으면 좋지 않습니다. 로 또한, 당신의 Lippert의 견적은 권한 착오에 호소 그는 또한 "그것의 좋은"이외의 아무것도 말하지 않는다.
DeadMG

나는 당신의 요점 @DeadMG를 주장하려고하지 않습니다-질문은 구체적으로 .NET의 모든 클래스가 전 세계적으로 Object 클래스에서 상속받는 이유였습니다. .NET 개발 팀이이 방법을 선택한 이유에 대해 합법적이지만 모호한 답변을 한 Microsoft가 대답합니다.
gws2

이 질문에 대한 답변이 너무 모호합니다.
DeadMG

4

Java 및 C # 디자이너는 무료 점심 과 같이 근본적으로 무료이기 때문에 루트 객체를 추가했다고 생각합니다 .

루트 객체를 추가하는 비용은 첫 번째 가상 기능을 추가하는 비용과 매우 같습니다. CLR과 JVM은 모두 객체 파이널 라이저가있는 가비지 수집 환경이므로 사용자 java.lang.Object.finalize또는 System.Object.Finalize분석법에 대한 가상 시스템이 하나 이상 있어야 합니다 . 따라서 루트 개체를 추가하는 비용은 이미 선불이므로 비용을 지불하지 않고도 모든 혜택을 누릴 수 있습니다. 공통 루트 클래스가 필요한 사용자는 원하는 것을 얻을 수 있고 덜 신경 쓰지 않는 사용자는없는 것처럼 프로그래밍 할 수 있습니다.


4

여기에 세 가지 질문이 있습니다. 하나는 공통 루트가 .NET에 도입 된 이유이고, 두 번째는 장점과 단점이며, 세 번째는 프레임 워크 요소가 전역을 갖는 것이 좋은 아이디어인지 여부입니다. 뿌리.

.NET에 공통 루트가있는 이유는 무엇입니까?

가장 기술적 인 의미에서, 공통 뿌리를 갖는 것은 반사와 제네릭 이전 컨테이너에 필수적 입니다.

또한 내 지식으로 는 Java equals()와 같은 기본 방법을 가진 공통 루트를 갖는 것이 hashCode()Java에서 매우 긍정적으로 받아 들여졌으며 C #은 Java의 영향을 받았으므로 그 기능도 원했습니다.

언어에 공통된 뿌리를 갖는 장점과 단점은 무엇입니까?

공통 루트를 갖는 장점 :

  • 당신은 허용 할 수 있는 모든 개체를 사용하면 다음과 같은 중요한 고려 특정 기능을 가지고 equals()hashCode(). 예를 들어 Java 또는 C #의 모든 객체를 해시 맵에서 사용할 수 있다는 것을 의미합니다.이 상황을 C ++과 비교하십시오.
  • 알 수없는 유형의 객체를 참조 할 수 있습니다. 예를 들어, 일반적인 제네릭 컨테이너처럼 정보를 전송하는 경우.
  • 알 수없는 유형의 오브젝트를 참조 할 수 있습니다 ( 예 : 리플렉션 사용시).
  • 드물기는하지만 서로 다르거 나 관련이없는 유형 (예 : printf-like 메소드 의 매개 변수)이 될 수있는 오브젝트를 허용하려는 경우에 사용할 수 있습니다 .
  • 하나의 클래스 만 변경하여 모든 객체의 동작을 변경할 수있는 유연성을 제공합니다. 예를 들어 C # 프로그램의 모든 개체에 메서드를 추가하려는 경우 확장 메서드를에 추가 할 수 있습니다 object. 아마도 흔하지는 않지만 공통의 뿌리가 없다면 불가능할 것입니다.

공통 루트를 갖는 단점 :

  • 더 정확한 유형을 사용할 수 있었더라도 어떤 값의 객체를 참조하는 것은 남용 될 수 있습니다.

프레임 워크 프로젝트에서 공통 루트를 사용해야합니까?

물론 매우 주관적이지만 위의 프로 콘 목록을 볼 때 나는 확실히 yes라고 대답 할 것 입니다. 특히, 프로 목록의 마지막 글 머리 기호-나중에 루트를 변경하여 모든 객체의 동작을 변경할 수있는 유연성-플랫폼에서 매우 유용하게됩니다. 플랫폼에서 루트에 대한 변경이 전체에 대한 변경보다 클라이언트에 의해 승인 될 가능성이 더 높습니다 언어.

게다가-이것은 훨씬 더 주관적이지만 공통 뿌리의 개념은 매우 우아하고 매력적입니다. 또한 일부 도구 사용이 더 쉬워집니다. 예를 들어 도구에 해당 공통 루트의 모든 하위 항목을 표시하고 프레임 워크 유형에 대한 빠르고 좋은 개요를 쉽게 요청할 수 있습니다.

물론, 그 유형은 적어도 약간 관련이 있어야하며, 특히 "is-a"규칙을 공통의 뿌리를 갖기 위해 희생하지 않을 것입니다.


c #은 단순히 Java의 영향을받은 것이 아니라 Java의 시점이라고 생각합니다. 마이크로 소프트는 더 이상 자바를 사용할 수 없었기 때문에 수십억 달러의 투자가 줄어들 것입니다. 그들은 이미 새로운 이름을 가진 언어로 시작했습니다.
Mike Braun

3

수학적으로 top 을 포함하는 유형 시스템을 사용하는 것이 조금 더 우아 하며 언어를 좀 더 완전하게 정의 할 수 있습니다.

프레임 워크를 작성하는 경우 기존 코드베이스가 반드시 소비합니다. 프레임 워크를 소비하는 모든 유형의 다른 유형이 존재하기 때문에 범용 수퍼 유형을 가질 수 없습니다.

에서 점, 결정은 공통 기본 클래스는 당신이 무슨 일을하는지에 달려있다합니다. 많은 일들이 일반적인 동작이 매우 드문, 그리고 혼자 공동 행동을 통해이 일을 참조하는 것이 유용하다.

그러나 일어난다. 그렇다면, 그 일반적인 행동을 추상화하십시오.


2

루트 객체 는 프레임 워크의 모든 클래스가 특정 작업 (해시 코드 가져 오기, 문자열로 변환, 동등 검사 등)을 지원 하기를 원했기 때문에 추진되었습니다 . C #과 Java 모두 Object의 모든 공통 기능을 루트 클래스에 배치하는 것이 유용하다는 것을 알았습니다.

이들이 OOP 원칙이나 다른 것을 위반하지 않는다는 것을 명심하십시오. Object 클래스의 모든 것은 시스템의 모든 서브 클래스 (읽기 : 모든 클래스)에서 의미가 있습니다. 이 디자인을 채택하기로 선택한 경우이 패턴을 따르십시오. 즉, 시스템의 모든 단일 클래스에 속하지 않는 것을 루트에 포함시키지 마십시오. 이 규칙을주의 깊게 따르면 전체 시스템에 유용한 공통 코드를 포함하는 루트 클래스가 없어야 할 이유가 없습니다.


2
전혀 사실이 아닙니다. 해시되지 않고 반영되지 않으며 문자열로 변환되지 않는 많은 내부 전용 클래스가 있습니다. 불필요한 상속과 불필요한 방법 많은 원칙에 위배됩니다.
DeadMG

2

몇 가지 이유, 모든 하위 클래스가 공유 할 수있는 공통 기능. 또한 프레임 워크 작성자에게 모든 기능을 사용할 수있는 다른 많은 기능을 프레임 워크에 작성할 수있는 기능을 제공했습니다. 예를 들어 ASP.NET 캐싱 및 세션이 있습니다. 객체를 받아들이는 add 메소드를 작성했기 때문에 거의 모든 것을 저장할 수 있습니다.

루트 클래스는 매우 유혹적 일 수 있지만 오용하기는 매우 쉽습니다. 대신 루트 인터페이스를 가질 수 있습니까? 그리고 하나 또는 두 개의 작은 방법이 있습니까? 아니면 프레임 워크에 필요한 것보다 훨씬 많은 코드를 추가합니까?

작성중인 프레임 워크의 모든 가능한 클래스에 어떤 기능을 제공해야하는지 궁금합니다. 모든 객체에서 실제로 사용됩니까? 아니면 그들 대부분에 의해? 루트 클래스를 만든 후에는 사람들이 임의의 기능을 추가하지 못하게하려면 어떻게해야합니까? 아니면 그들이 "전역"이 되고자하는 임의의 변수?

몇 년 전에 루트 클래스를 만든 매우 큰 응용 프로그램이있었습니다. 몇 달 간의 개발 끝에 비즈니스가 없었던 코드로 채워졌습니다. 우리는 이전 ASP 응용 프로그램을 변환하고 있었고 루트 클래스는 과거에 사용했던 이전 global.inc 파일로 대체되었습니다. 그 교훈을 어려운 방법으로 배웠습니다.


2

모든 독립형 힙 객체는 Object; 모든 독립형 힙 객체에는 유형을 식별하는 수단과 같은 특정 공통 측면이 있어야하기 때문에 의미가 있습니다. 그렇지 않으면 가비지 수집기에서 알 수없는 형식의 힙 객체에 대한 참조가 있으면 해당 객체와 관련된 메모리 Blob 내에서 어떤 비트가 다른 힙 객체에 대한 참조로 간주되는지 알 수있는 방법이 없습니다.

또한, 타입 시스템 내에서, 구조의 멤버와 클래스의 멤버를 정의하기 위해 동일한 메커니즘을 사용하는 것이 편리합니다. 값 유형 저장 위치 (변수, 매개 변수, 필드, 배열 슬롯 등)의 동작은 클래스 유형 저장 위치의 동작과 매우 다르지만 이러한 동작 차이는 소스 코드 컴파일러 및 실행 엔진 ( 타입 시스템으로 표현되는 것이 아니라 JIT 컴파일러).

그 결과 값 유형을 정의하면 스토리지 위치 유형과 힙 객체 유형의 두 가지 유형이 효과적으로 정의됩니다. 전자는 암시 적으로 후자로 변환 될 수 있고, 후자는 타입 캐스트를 통해 전자로 변환 될 수있다. 두 유형의 변환 모두 문제의 유형의 한 인스턴스에서 다른 필드로 모든 공용 및 개인 필드를 복사하여 작동합니다. 또한 일반 제약 조건을 사용하여 복사본을 먼저 만들지 않고도 값 형식 저장소 위치에서 직접 인터페이스 멤버를 호출 할 수 있습니다.

값 유형 힙 객체에 대한 참조는 값 유형이 아닌 클래스 참조처럼 동작하기 때문에이 모든 것이 중요합니다. 예를 들어 다음 코드를 고려하십시오.

string testEnumerator <T> (T it) 여기서 T : IEnumerator <string>
{
  var it2 = 그것;
  it.MoveNext ();
  it2.MoveNext ();
  그것을 돌려줍니다.
}
공공 무효 시험 ()
{
  var theList = new List <문자열> ();
  theList.Add ( "Fred");
  theList.Add ( "George");
  theList.Add ( "Percy");
  theList.Add ( "Molly");
  theList.Add ( "Ron");

  var enum1 = theList.GetEnumerator ();
  IEnumerator <문자열> enum2 = enum1;

  Debug.Print (testEnumerator (enum1));
  Debug.Print (testEnumerator (enum1));
  Debug.Print (testEnumerator (enum2));
  Debug.Print (testEnumerator (enum2));
}

testEnumerator()메소드에 값 유형의 저장 위치가 전달 되면 전달 된 값에서 it퍼블릭 및 프라이빗 필드가 복사 된 인스턴스가 수신됩니다. 로컬 변수 it2는 필드가 모두에서 복사 된 다른 인스턴스를 보유 it합니다. 부름MoveNext 에하는 것은 it2영향을주지 않습니다 it.

위 코드에 클래스 유형의 저장 위치가 전달되면 전달 된 값은 it , 그리고 it2, 모두 같은 객체를 참조하고, 따라서 호출 MoveNext()그 중 효과적으로 그들 모두에 그것을 호출에.

효과적으로 캐스팅 하면 값 유형에서 클래스 유형 List<String>.Enumerator으로 IEnumerator<String>효과적으로 전환됩니다. 힙 객체의 유형은 동일 List<String>.Enumerator하지만 동작이 동일한 이름의 값 유형과는 매우 다릅니다.


ToString ()을 언급하지 않은 +1
JeffO

1
이것은 구현 세부 사항에 관한 것입니다. 이를 사용자에게 노출시킬 필요가 없습니다.
DeadMG

@DeadMG : 무슨 뜻인가요? a List<T>.Enumerator로 저장된 a의 관찰 가능한 동작 은에 저장된 a List<T>.Enumerator의 동작과 크게 다르며 IEnumerator<T>, 이전 유형의 값을 두 유형의 저장 위치에 저장하면 열거 자의 상태를 복사합니다. 후자 유형의 값을 또한 후자 유형 인 저장 위치에 저장하는 동안 사본을 만들지 않을 것이다.
supercat

예,하지만 그 사실과 Object아무 관련없습니다 .
DeadMG

@DeadMG : 내 요점은 유형의 힙 인스턴스 System.Int32도의 인스턴스 System.Object이지만 유형의 저장 위치 System.Int32에는 System.Object인스턴스 또는 참조가 없습니다.
supercat

2

이 디자인은 스몰 토크를 거슬러 올라갑니다. 저는 거의 모든 다른 관심사를 희생시키면서 객체 지향을 추구하려는 시도라고 생각합니다. 따라서 다른 기술이 아마도 (또는 확실히) 우수 할 때에도 객체 지향을 사용하는 경향이 있습니다.

Object루트에 (또는 비슷한) 단일 계층 구조가 있으면 (예를 들어) 컬렉션 클래스를 컬렉션으로 만드는 것이 매우 쉽습니다.Object 지므로 컬렉션에 모든 종류의 개체를 포함하는 것은 쉽지 않습니다.

이 약간의 이점에 대한 대가로, 당신은 모든 단점을 얻습니다. 먼저, 디자인 관점에서, 당신은 정말로 미친 아이디어를 얻습니다. 적어도 우주에 대한 자바의 견해에 따르면 무신론과 숲은 공통점이 무엇입니까? 둘 다 해시 코드를 가지고 있습니다! 지도가 컬렉션인가요? 자바에 따르면, 그렇지 않다!

70 년대 스몰 토크가 설계되었을 때, 아무도 합리적인 대안을 설계하지 않았기 때문에 이런 종류의 말도 안되는 것이 받아 들여졌습니다. 스몰 토크는 1980 년에 마무리되었고 1983 년에는 제네릭을 포함한 Ada가 디자인되었다. Ada는 일부 사람들이 예측 한 종류의 인기를 얻지 못했지만, 그 제네릭은 모 놀리 식 계층 구조에 내재 된 광기가 없는 임의의 유형의 개체 모음을 지원하기에 충분했습니다 .

Java (및 .NET)가 설계 될 때 모 놀리 식 클래스 계층 구조는 아마도 문제가 있지만 대부분 알려진 문제인 "안전한"선택으로 여겨졌을 것입니다 . 대조적으로, 일반적인 프로그래밍은 거의 모든 사람 (이전까지도)이 이론적으로는 이 문제에 대한 이론적 으로 훨씬 더 나은 접근 방식 이지만 , 많은 상업적 지향 개발자가 탐색 및 / 또는 위험성이 낮은 (즉, 상업 세계에서) 생각한 것입니다. Ada는 실패로 크게 기각되었습니다).

그래도 명확하게 보자. 모 놀리 식 계층 구조는 실수였습니다. 그 실수의 이유는 적어도 이해할 수 있었지만 어쨌든 실수였습니다. 나쁜 디자인이며 디자인 문제는 그것을 사용하는 거의 모든 코드에 퍼져 있습니다.

그러나 오늘날 새로운 디자인에는 합리적인 질문이 없습니다. 모 놀리 식 계층 구조를 사용하는 것은 명백한 실수이며 나쁜 생각입니다.


.NET이 출시되기 전에 템플릿이 훌륭하고 유용한 것으로 알려졌습니다.
DeadMG

상업용 세계에서 Ada 그다지 많지 않고 운영 체제 서비스에 대한 표준화 된 인터페이스가 없기 때문에 실패했습니다. 파일 시스템, 그래픽, 네트워크 등에 대한 표준 API는 '호스트 된'애플리케이션의 Ada 개발을 매우 비싸게 만들었습니다.
케빈 클라인

@ kevincline : 아마 Ada가 시장에서의 실패로 인해 실패로 기각되었다는 효과에 대해 약간 다르게 말했을 것입니다. Ada의 사용을 거부하는 것은 (IMO) 상당히 합리적이었습니다.하지만 그로부터 배우는 것을 거부하는 것이 가장 좋습니다.
Jerry Coffin

@ Jerry : C ++ 템플릿이 Ada 제네릭의 아이디어를 채택 한 다음 암시 적 인스턴스화로 크게 개선했다고 생각합니다.
케빈 클라인

1

당신이하고 싶은 것은 실제로 흥미 롭습니다. 완료 될 때까지 그것이 잘못되었거나 옳은지를 증명하기는 어렵습니다.

고려해야 할 사항은 다음과 같습니다.

  • 이 최상위 객체를 좀 더 구체적인 객체에 의도적으로 전달한 적이 언제입니까?
  • 수업 중 하나 하나에 어떤 코드를 넣으시겠습니까?

그것들은 공유 루트에서 혜택을 볼 수있는 유일한 두 가지입니다. 언어에서는 몇 가지 매우 일반적인 방법을 정의하고 아직 정의되지 않은 객체를 전달할 수 있지만 사용하지 않는 객체를 전달할 수 있습니다.

또한 개인적인 경험에서 :

스몰 토크라는 배경을 가진 개발자가 작성한 툴킷을 사용했습니다. 그는 모든 "데이터"클래스를 단일 클래스로 확장했으며 모든 메소드가 해당 클래스를 채택했습니다. 문제는 서로 다른 데이터 클래스가 항상 상호 교환 가능하지 않다는 것입니다. 따라서 이제 편집자와 컴파일러는 주어진 상황에 전달할 내용에 대한 도움을 줄 수 없었으며 항상 도움이되지 않는 그의 문서를 참조해야했습니다. .

그것은 내가 다루어야했던 가장 사용하기 어려운 라이브러리였습니다.


0

그것이 OOP의 방식이기 때문입니다. 무엇이든 참조 할 수있는 유형 (객체)이 있어야합니다. 객체 유형의 인수는 무엇이든 받아 들일 수 있습니다. 상속도 있습니다. ToString (), GetHashCode () 등이 무엇이든 가능하다는 것을 확신 할 수 있습니다.

오라클조차도 이러한 기본 유형의 중요성을 인식했으며 2017 년에 Java에서 기본 요소를 제거 할 계획입니다.


6
그것은 OOP의 방법이 아니며 중요하지도 않습니다. "좋은 것"이외의 실제 주장은 없습니다.
DeadMG

1
@DeadMG 첫 문장을 지나서 인수를 읽을 수 있습니다. 프리미티브는 객체와 다르게 동작하므로 프로그래머는 객체와 프리미티브에 대해 동일한 목적 코드의 많은 변형을 작성해야합니다.
단테

2
@DeadMG 잘 그는 모든 객체에 있다고 가정 ToString()하고 할 수 있음을 의미한다고 말했다 GetType(). 유형의 변수를 사용하여 object.NET 객체를 저장할 수 있음을 지적하는 것이 좋습니다 .
JohnL

또한 모든 유형의 참조를 보유 할 수있는 사용자 정의 유형을 작성하는 것이 완벽하게 가능합니다. 이를 달성하기 위해 특별한 언어 기능이 필요하지 않습니다.
DeadMG

특정 코드가 포함 된 수준의 개체 만 있어야하며 그래프를 연결하는 개체는 없어야합니다. "객체"는 실제로 몇 가지 중요한 방법을 구현하고 유형이 아직 생성되지 않은 툴링에 객체를 전달하는 방법으로 작동합니다.
Bill K
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.