침체 및 낙상


88

저는 C # (및 OOP )을 처음 사용합니다 . 다음과 같은 코드가있을 때 :

class Employee
{
    // some code
}


class Manager : Employee
{
    //some code
}

질문 1 :이 작업을 수행하는 다른 코드가있는 경우 :

   Manager mgr = new Manager();
   Employee emp = (Employee)mgr;

여기 Employee에는 Manager있지만 그렇게 캐스트하면 내가 업 캐스트 Employee한다는 의미입니까?

질문 2 :

여러 개의 Employee클래스 객체가 있고 일부가 아닌 Manager경우 가능한 경우 어떻게 다운 캐스트 할 수 있습니까?


6
업 캐스팅은 명시적인 캐스트없이 수행 할 수 있습니다. 그래서 Employee emp= mgr;충분합니다.
내 겨드랑이 키스

답변:


93
  1. 맞아요. 그렇게 할 때 그것을 employee객체 로 캐스팅하는 것이므로 관리자와 관련된 어떤 것도 액세스 할 수 없습니다.

  2. 다운 캐스팅은 기본 클래스를 수강 한 다음보다 구체적인 클래스로 전환하는 것입니다. is 및 다음과 같은 명시 적 캐스트를 사용하여 수행 할 수 있습니다.

    if (employee is Manager)
    {
        Manager m = (Manager)employee;
        //do something with it
    }
    

또는 다음과 같은 as연산자로 :

Manager m = (employee as Manager);
if (m != null)
{
    //do something with it
}

불명확 한 점이 있으면 기꺼이 정정하겠습니다!


다운 캐스팅이 무엇인지 알기위한 예제가 필요합니까?
user184805 2009-10-06

4
잘 정립 된 용어를 재정의하지 마십시오. OOP 및 C #의 맥락에서 "박싱"은 다소 다른 의미 (= 값 유형 개체를 참조로 래핑)를 의미합니다. 또한 귀하의 예제는 as대신 is캐스트 뒤에 연산자를 사용할 수 있습니다 .
Konrad Rudolph

2
나는 첫 번째 요점에서 정정하고 두 가지 방법을 모두 보여주기 위해 내 대답의 후반부를 변경했습니다.
RCIX

3
첫 번째 진술 ( "... [관리자 클래스의 인스턴스]을"직원 "개체로 캐스팅 [..]은 관리자와 관련된 어떤 것도 액세스 할 수 없음을 의미합니다.")은 완전히 정확하지 않습니다. OP의 예에서 Employee에 Manager에서 재정의 된 가상 멤버가있는 경우 CLR은 캐스트에 관계없이 Manager 구현을 호출합니다. C #의 다형성에 대한 MSDN 문서에서 : "파생 클래스가 가상 멤버를 재정의하면 해당 클래스의 인스턴스가 기본 클래스의 인스턴스로 액세스되는 경우에도 해당 멤버가 호출됩니다." MSDN에서 제공하는 예제는 거의 동일합니다.
Antony

49

업 캐스팅 (사용 (Employee)someInstance)은 일반적으로 컴파일러가 유형이 다른 유형에서 파생 된 경우 컴파일 시간에 알려줄 수 있으므로 쉽습니다.

그러나 다운 캐스팅 은 일반적으로 런타임에 수행되어야합니다. 컴파일러가 문제의 인스턴스가 주어진 유형인지 항상 알 수있는 것은 아니기 때문입니다. C #은이 두 개의 연산자를 제공합니다 - 이다 내리 뜬 작동 여부를 알려줍니다, 참 /의 거짓을 반환합니다. 그리고 하는 시도는 캐스팅을하고 올바른 유형 가능한 경우는 null이 아니라면를 반환합니다.

직원이 관리자인지 테스트하려면

Employee m = new Manager();
Employee e = new Employee();

if(m is Manager) Console.WriteLine("m is a manager");
if(e is Manager) Console.WriteLine("e is a manager");

이것을 사용할 수도 있습니다

Employee someEmployee = e  as Manager;
    if(someEmployee  != null) Console.WriteLine("someEmployee (e) is a manager");

Employee someEmployee = m  as Manager;
    if(someEmployee  != null) Console.WriteLine("someEmployee (m) is a manager");

11
  • 업 캐스팅 은 하위 클래스 참조에서 기본 클래스 참조를 만드는 작업입니다. (하위 클래스-> 수퍼 클래스) (예 : 관리자-> 직원)
  • 다운 캐스팅 은 기본 클래스 참조에서 하위 클래스 참조를 만드는 작업입니다. (수퍼 클래스-> 하위 클래스) (예 : 직원-> 관리자)

귀하의 경우

Employee emp = (Employee)mgr; //mgr is Manager

당신은 업 캐스팅을하고 있습니다.

업 캐스트는 런타임에 잠재적으로 실패 할 수 있기 때문에 명시 적 캐스트가 필요한 다운 캐스트와 달리 항상 성공합니다. ( InvalidCastException ).

C #은이 예외가 발생하지 않도록 두 가지 연산자를 제공합니다.

시작 :

Employee e = new Employee();

먼저:

Manager m = e as Manager; // if downcast fails m is null; no exception thrown

둘째:

if (e is Manager){...} // the predicate is false if the downcast is not possible 

경고 : 업 캐스트를 할 때 슈퍼 클래스의 메서드, 속성 등에 대해서만 액세스 할 수 있습니다.


6

각 Employee 개체가 Manager 개체인지 확인해야하는 경우 OfType 메서드를 사용합니다.

List<Employee> employees = new List<Employee>();

//Code to add some Employee or Manager objects..

var onlyManagers = employees.OfType<Manager>();

foreach (Manager m in onlyManagers) {
  // Do Manager specific thing..
}

2

답변 1 : 예, 그것은 업 캐스팅이라고 불렀지 만 당신이하는 방식은 현대적인 방식이 아닙니다. 업 캐스팅은 변환이 필요하지 않고 암시 적으로 수행 될 수 있습니다. 그래서 그냥 Employee emp = mgr; 업 캐스팅에 충분합니다.

답 2 : Manager 클래스의 객체를 생성하면 매니저가 직원이라고 말할 수 있습니다. 때문에 클래스 관리자 : 직원이 묘사 되어-A 관계 직원 클래스와 관리자 클래스 사이를. 그래서 우리는 모든 관리자가 직원이라고 말할 수 있습니다.

그러나 Employee 클래스의 객체를 생성하면 Employee 클래스는 다른 클래스를 상속하지 않는 클래스이므로이 직원이 관리자라고 말할 수 없습니다 . 따라서 Employee Class 객체를 Manager Class 객체로 직접 다운 캐스트 할 수 없습니다.

따라서 대답은 Employee Class 객체에서 Manager Class 객체로 다운 캐스트하려면 먼저 Manager Class 객체를 가져야하고 업 캐스트 한 다음 다운 캐스트 할 수 있습니다.


-1

업 캐스팅 및 다운 캐스팅 :

업 캐스팅 : 파생 클래스에서 기본 클래스로 캐스팅 다운 캐스팅 : 기본 클래스에서 파생 클래스로 캐스팅

예와 동일하게 이해합시다.

다음과 같이 정의 된 두 클래스 Shape를 My parent 클래스로, Circle을 Derived 클래스로 간주합니다.

class Shape
{
    public int Width { get; set; }
    public int Height { get; set; }
}

class Circle : Shape
{
    public int Radius { get; set; }
    public bool FillColor { get; set; }
}

업 캐스팅 :

모양 s = new Shape ();

원 c = s;

c와 s는 모두 동일한 메모리 위치를 참조하지만 둘 다 다른 뷰를 가지고 있습니다. 즉, "c"참조를 사용하면 기본 클래스와 파생 클래스의 모든 속성에 액세스 할 수 있지만 "s"참조를 사용하면 속성에 액세스 할 수 있습니다. 유일한 부모 클래스의.

업 캐스팅의 실제 예는 .net 프레임 워크의 모든 유형의 스트림 리더의 기본 클래스 인 Stream 클래스입니다.

StreamReader 리더 = new StreamReader (new FileStreamReader ());

여기서 FileStreamReader ()는 streadm reder로 업 캐스팅됩니다.

다운 캐스팅 :

모양 s = new Circle (); 여기에서 위에서 설명한 것처럼 s의 뷰는 유일한 부모입니다.

var c = (원) s;

다운 캐스팅의 실제 예는 WPF의 버튼 클래스입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.