2013-02-25 3 views
0

C#에서 기본 OOPS 개념에 대한 이해를 분명히하고 싶습니다. 대부분의 인터넷 사이트에서 기본 클래스의 private 멤버 인 을 상속 받지만 에 액세스 할 수 없습니다.파생 클래스가 기본 클래스의 private 멤버를 상속하는 경우 생성자가 아닌 이유는 무엇입니까?

파생 클래스는 public, protected, internal 및 보호 된 기본 클래스의 내부 멤버에 액세스 할 수 있습니다. 파생 된 클래스가 기본 클래스의 개인 멤버를 상속 받았지만 해당 멤버에 에 액세스 할 수 없습니다. 그러나 모든 해당 전용 멤버는 여전히 파생 클래스 에 존재하며 기본 클래스 에서 수행 할 것과 동일한 작업을 수행 할 수 있습니다. 예를 들어, 보호 된 기본 클래스 메소드 이 개인 필드에 액세스한다고 가정합니다. 상속 된 기본 클래스 메서드가 제대로 작동하려면 해당 필드가 파생 된 클래스에 있어야합니다.

출처 : http://msdn.microsoft.com/en-us/library/ms173149.aspx

우리가 다음 우리는 는 "기본 클래스의 생성자는 파생 클래스에서 상속되지만, 파생 클래스는 전용 액세스 /를 통해 호출 할 수 있습니다 말할 수있는, 올바른 위의 고려한다면 내 질문은, 파생 클래스 ""인스턴스를 생성하는 동안 기본 키워드와이 생성자를 사용하는 자체 생성자를 외부에서 사용할 수 없습니다. 기본 클래스 생성자를 호출하기 때문에

public class Employee 
{ 
    public int salary; 

    public Employee(int annualSalary) 
    { 
     salary = annualSalary; 
    } 
} 

public class Manager : Employee 
{ 
    public Manager(int annualSalary) 
     : base(annualSalary) 
    { 
     //Add further instructions here. 
    } 
} 

그것은 내부 클래스 존재하여야한다. 어쩌면 제 해석이 잘못되었을 수도 있습니다. 아무도 이것을 설명 할 수 있습니까?

미리 감사드립니다.

+0

"파생 클래스는 기본 클래스의 내부 ... 멤버에 액세스 할 수 있습니다."두 클래스가 동일한 어셈블리에있는 경우에만 true입니다. – Henrik

+1

그리고 문제/질문은 정확히 무엇입니까? 기본 생성자를 호출하는 방법과 클래스가 초기화되는 방법을 알고 있습니다. 그렇다면 기본 생성자가 실제로 "존재"하는 것이 왜 중요합니까? –

+0

기본 클래스 생성자를 호출하여 파생 클래스 객체를 만들 수 있는지 묻고 있습니까? –

답변

1

"현재"를 정의하는 방법에 따라 다릅니다. "어딘가에 사용할 수있는"것으로 정의하면 기본 클래스의 전용 멤버는 생성자뿐만 아니라 "현재"입니다. "현재"를 "해당 특정 클래스에서 발견됨"으로 정의하면 둘 다 "현재"가 아닙니다.

리플렉션을 사용해보세요. 기본 클래스에서 비공개 멤버를 찾을 수 없습니다. 전용 멤버는 상속되므로 사용할 수 있지만 기본 클래스에서만 사용할 수 있습니다.

그래서 생성자가 있습니다.

끝에
class A 
    { 
     private A(int i) { } 
     public A() { } 
     private void Foo() { } 
     public void Bar() { } 
    } 

    class B : A 
    { 

    } 

    var aProperties = typeof(A).GetMembers(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy); 
    // you won't see Foo in this line, nor any constructors of A 
    var bProperties = typeof(B).GetMembers(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy); 

, 당신은 말할 수있다 : 기본 클래스의

  • 모든 구성원은 어떻게 든 측면에서 실행을 위해 사용할 수 존재한다.
  • 상속 클래스에서 개인 멤버를 호출하는 구문은 없으며 클래스 외부의 아무 곳에서도 호출 할 수 없습니다.
  • 기본 클래스의 생성자는 base 키워드를 사용하는 생성자에서만 호출 할 수 있습니다. (생성자는 이고 계층 구조의 각 기본 클래스에서 항상이 호출됩니다. 지정하지 않으면 기본 생성자입니다.)
  • 클래스에 의해 선언 (또는 재정의) 된 멤버 만 실제로 해당 "내부"에 있음을 알 수 있습니다. 수업. 리플렉션을 사용하면 BindingFlags.FlattenHierarchy을 사용하여 표시되는 멤버를 기본 클래스에서 병합 할 수 있습니다. private 멤버와 생성자는 선언 클래스에서만 발견됩니다.
+0

귀하의 대답은 질문의 정보와 직접적으로 모순되며 MSDN에서 제공되는 질문의 해석에 무엇이 잘못되었는지 설명하지 않습니다. – hvd

+0

"present"를 정의하는 방법에 따라 다릅니다. "어딘가에 사용할 수있는"것으로 정의하면 기본 클래스의 전용 멤버는 생성자뿐만 아니라 "현재"입니다. "현재"를 "해당 특정 클래스에서 발견됨"으로 정의하면 둘 다 "현재"가 아닙니다. MSDN 발췌 부분에는 생성자에 대한 내용이 없습니다. 저는 개인 회원이 생성자로서 더 이상 존재하지 않는다고 말합니다. –

+0

그게 더 합리적입니다. 나는 * 생성자가 private 멤버가 아니라 실제 코드에 영향을주지 않는 방법으로 실제로 액세스 할 수 있다고 생각한다. – hvd

1

Manager을 구성하려면 기본 클래스에 생성자를 사용하여 기본 클래스를 구성해야합니다 (이 경우). 그렇다고해서 동일한 서명으로 생성자를 정의해야한다는 것은 아닙니다.

당신은 또한이 작업을 수행하도록 허용 될 것입니다 : 당신은 힙에 새로운 객체를 할당합니다 Manager 당신의 건설 기간 동안

public Manager() : base(100000) 
{ 
} 

또는

public Manager(string name, int salary) : base (salary) 
{ 
    // store name 
} 

. 이 객체는 기본 클래스 ( Employee) 및 콘크리트 클래스 ( Manager)에 정의 된 변수를 저장할 수 있도록 충분한 메모리를 요구합니다.

+0

미안하지만, 내 질문에 파생 클래스 생성자를 정의하는 방법에 대한되지 않습니다. 기본 키워드를 사용하여 기본 클래스 생성자를 호출하는 방법을 나타 내기 위해 추가 한 예제입니다. 내가 찾고있는 "기본 클래스 생성자 파생 된 클래스에서 상속 된"문에 대한 설명입니다. – Sambhaji

0

은 "기본 클래스의 생성자는 파생 클래스에서 상속되지만, 파생 클래스는 액세스/기본 키워드를 사용하여 자신의 생성자 를 통해 호출 할 수 있습니다 및 작성하는 동안이 생성자는 외부 세계에 사용할 수 없습니다 파생 된 클래스의 인스턴스 "라고합니다.

네, 맞습니다.

기본 클래스 생성자를 호출하려면 해당 클래스가 내부에 있어야합니다.

개인 또는 보호 된 기본 멤버와 마찬가지로 "현재"이지만 외부에는 액세스 할 수 없습니다.

0

클래스가 모든 상위 클래스 생성자에 대해 시스템이 서명과 액세스가 동일한 하위 클래스 생성자의 존재를 유추해야한다고 지정할 수있는 방법이 있다면 도움이 될 것입니다 필드 이니셜 라이저와 체인을 해당 기본 생성자에 연결합니다. 특정 요청으로 이러한 기능을 사용 가능하게하면 버그가 발생하지 않을 것입니다. 파생 클래스가 생성자를 지정하지 않을 때 (기본 매개 변수가없는 생성자에 연결되는 매개 변수가없는 생성자를 추론하는 것과는 대조적으로) 추론 일지라도 언어 디자인 기능인 경우에는 매우 안전합니다. 그러나 매개 변수없는 생성자를 노출하고자하는 파생 클래스의 작성자는 매개 변수가없는 생성자를 표시하지 않으므로 컴파일러에서 매개 변수없는 생성자 만 유추 할 것으로 예상되므로 생성자가 포함되지 않았을 수 있으므로 기존 프레임 워크에 적용하면 좋지 않습니다.).

그러나 파생 된 클래스에 자체적으로 중요한 생성자가 없으면 하위 클래스는 그 중 하나를 통과하지 않고 만든 개체를 만들 의도가 없습니다. 부모 클래스는 매개 변수화 된 생성자와 사람이 쓰기 만 가정합시다 :

class Child : Parent 
{ 
    Thing blah; 
    Child() 
    { 
     blah = new Thing(); 
    } 
} 

새로운 일에 blah 세트가됩니다 생성 된 모든 Child. 이제 새로운 버전의 기본 클래스가 Name 속성을 추가하고 이름을 지정하는 생성자를 추가한다고 가정합니다.생성자가 자동 ​​상속 된 경우 myChild = new Child("Fred");이라는 코드는 Parent의 생성자에 연결되지만 blah은 새로운 Thing으로 설정되지 않습니다.

안전한 생성자 "상속"은 클래스가 부모 생성자에 연결하고 자식 클래스 불변성을 설정하기 위해 지정된 코드 블록을 실행하여 모든 인스턴스를 생성해야한다고 지정할 수있는 경우 가능할 수 있습니다. 그러나 이러한 기능은 구현하기가 다소 복잡 할 수 있으며 비용이 들게 될지 확실하지 않습니다.

관련 문제