C++, Java에서의 업캐스팅(Upcasting), 다운캐스팅(Downcasting)

  • 정리하다가 홀딩…

C++

업캐스팅(Upcasting)

  • 베이스 클래스의 포인터나 참조로부터 파생 클래스의 포인터나 참조를 생성하는 과정을 업캐스팅(Upcasting)이라고 한다.
  • 파생 클래스의 참조 또는 포인터를 기본 클래스로 변환하는 데 사용되는 업캐스팅을 의미합니다.
  • 업캐스팅은 다운캐스팅에 비해 안전한 캐스팅입니다.
  • 명시적 형식 변환 없이 한 클래스에서 다른 클래스로 참조를 암시적으로 캐스팅하는 공개 상속을 허용합니다.
  • 기본적으로 업캐스팅 생성은 기본 클래스와 파생 클래스 간의 관계입니다.
  • 업캐스팅 은 파생 클래스 참조 또는 포인터를 기본 클래스로 변환하는 것입니다.
    • 즉, 업캐스팅을 통해 파생 유형을 기본 유형인 것처럼 취급할 수 있습니다.
    • 명시적 유형 캐스트 ​​없이 항상 공개 상속이 허용됩니다.
    • 이것은 기본 클래스와 파생 클래스 간의 is-관계 의 결과 입니다 .
  • 자식 개체는 부모 개체 의 모든 데이터 멤버와 멤버 기능을 상속한다는 점에서 부모 개체입니다. 따라서 부모 개체에 대해 할 수 있는 모든 작업을 자식 개체에 대해 수행할 수 있습니다. 따라서 부모 포인터(참조) 를 처리하도록 설계된 함수는 문제 없이 자식 개체 에 대해 동일한 작업을 수행할 수 있습니다. 객체에 대한 포인터를 함수 인수로 전달하는 경우에도 동일한 아이디어가 적용됩니다. 업캐스팅은 전이적 입니다. Parent 에서 Child 클래스를 파생하면 Parent 포인터 (참조)는 Parent 또는 a 를 참조할 수 있습니다.자식 개체입니다.

  • 업캐스팅은 foo(Base 파생된 _obj ) 에서와 같이 파생 클래스 개체가 기본 클래스 개체로 값으로 전달될 때 개체 슬라이싱 을 유발할 수 있습니다 .
Base *ptr = &derived_obj;  
  • 파생 클래스는 데이터 멤버와 멤버 함수를 포함하는 모든 기본 클래스 속성을 상속하여 기본 개체와 마찬가지로 파생 클래스 개체를 사용하여 함수를 실행할 수 있습니다.
#include <iostream>  
using namespace std;  
class Base  
{  
    public:  
        void disp()  
    {  
        cout << " It is the Super function of the Base class ";  
    }  
};  
  
class derive : public Base  
{  
    public:  
        void disp()  
        {  
            cout << "\n It is the derive class function ";  
        }  
      
};  
  
int main ()  
{  
    // create base class pointer  
    Base *ptr;  
      
    derive obj; // create object of derive class  
    ptr = &obj; // assign the obj address to ptr variable  
      
    // create base class's reference  
     Base &ref = obj;   
    // Or  
    // get disp() function using pointer variable  
      
    ptr->disp();  
    return 0;  
}  
  • output
It is the Super function of the Base class

다운캐스팅 (Downcasting)

  • 다운캐스팅은 기본 클래스의 포인터 또는 참조를 파생 클래스의 포인터 또는 참조로 변환하는 업캐스팅의 반대 프로세스입니다.
  • 기본 클래스의 개체를 파생 클래스의 개체로 수동으로 캐스팅하므로 명시적 형식 변환을 지정해야 합니다.
  • 다운캐스팅은 대부분의 경우 is- 관계를 따르지 않습니다 .
  • 업캐스팅만큼 안전하지 않습니다. 또한 파생 클래스는 다음과 같은 새로운 기능을 추가할 수 있습니다. 새로운 데이터 멤버와 이러한 데이터 멤버를 사용하는 클래스 멤버의 기능. 그러나 이러한 기능은 기본 클래스에 적용할 수 없습니다.
  • 반대 프로세스인 기본 클래스 포인터(참조)를 파생 클래스 포인터(참조)로 변환하는 것을 다운캐스팅 이라고 합니다
  • 명시적 유형 캐스트가 없으면 다운캐스팅이 허용되지 않습니다. 이 제한의 이유는 is- 관계 가 대부분의 경우 대칭이 아니기 때문입니다. 파생 클래스는 새 데이터 멤버를 추가할 수 있으며 이러한 데이터 멤버를 사용하는 클래스 멤버 함수는 기본 클래스에 적용되지 않습니다.

  • C++는 이 변환을 수행하는 dynamic_cast 라는 특별한 명시적 캐스트를 제공합니다 . 다운캐스팅은 파생 클래스의 개체를 항상 기본 클래스의 변수에 할당할 수 있다는 기본 개체 지향 규칙의 반대입니다. 업캐스팅에 대한 한 가지 더:
  • 암시 적 업캐스팅 을 사용하면 기본 클래스 포인터(참조)가 기본 클래스 개체 또는 파생 클래스 개체를 참조할 수 있으므로 동적 바인딩 이 필요합니다 . 이것이 우리가 가상 멤버 함수를 가지고 있는 이유입니다.
    • 포인터(참조) 유형: 컴파일 시간에 알려짐.
    • 개체 유형: 런타임 까지 알 수 없음 .
Derived *d_ptr = &b_obj;  
  • 예제
#include <iostream>  
using namespace std;  
class Parent  
{  
    public:  
        void base()  
        {  
            cout << " It is the function of the Parent class "<< endl;   
        }  
};  
  
class Child : public Parent  
{  
    public:  
        void derive()  
        {  
            cout << " it is the function of the Child class " <<endl;  
        }  
};  
  
int main ()  
{  
    Parent pobj; // create Parent's object  
    Child *cobj; // create Child's object  
      
    // explicit type cast is required in downcasting  
    cobj = (Child *) &pobj;  
    cobj -> derive();  
      
    return 0;  
}  
  • output
It is the function of the Child class
  • 복합 예제
#include <iostream>  
using namespace std;  
  
class Parent {  
    private:  
        int id;  
          
    public:  
        void showid ()  
        {  
            cout << " I am in the Parent class " << endl;  
            }     
};  
  
class Myson : public Parent {  
    public:  
        void disp ()  
        {  
            cout << " I am in the Myson class " << endl;  
        }  
};  
  
int main ( int argc, char * argv[])  
{  
    // create object of the Parent class  
    Parent par_obj;  
      
    // create object of the Myson class  
    Myson my_obj;  
      
    // upcast - here upcasting can be done implicitly  
    Parent *ptr1 = &my_obj; // base class's reference the derive class's object  
      
    // downcast - here typecasting is done explicitly   
    Myson *ptr2 = (Myson *) &par_obj;  
      
    // Upcasting is safe:  
    ptr1->showid();  
    ptr2->showid();  
      
      
    // downcasting is unsafe:  
    ptr2->disp();  
      
    getchar();  
    return 0;  
      
}  

  • output
I am in the Parent class
I am in the Parent class
I am in the Myson class

java

  • 데이터 유형과 마찬가지로 객체도 유형 변환될 수 있습니다. 그러나 객체에는 부모 객체와 자식 객체라는 두 가지 유형의 객체만 있습니다. 따라서 객체의 유형 캐스팅은 기본적으로 한 유형의 객체(즉, 자식 또는 부모가 다른 객체로)를 의미합니다. 유형 캐스팅에는 두 가지 유형이 있습니다. 그들은:

  • 업캐스팅:
    • 업캐스팅 은 자식 개체를 부모 개체로 유형 변환하는 것 입니다.
    • 업캐스팅은 암시적으로 수행할 수 있습니다.
    • 업캐스팅은 상위 클래스 멤버에 액세스할 수 있는 유연성을 제공하지만 이 기능을 사용하여 모든 하위 클래스 멤버에 액세스하는 것은 불가능합니다.
    • 모든 멤버 대신 자식 클래스의 일부 지정된 멤버에 액세스할 수 있습니다. 예를 들어 재정의된 메서드에 액세스할 수 있습니다.
  • 다운캐스팅 :
    • 마찬가지로 다운캐스팅은 부모 개체를 자식 개체로 유형 변환하는 것을 의미합니다 . 다운캐스팅은 암시적일 수 없습니다.
  • 업캐스팅은 암시적 또는 명시적으로 수행할 수 있지만 다운캐스팅은 암시적으로 가능하지 않습니다.

업캐스팅(Upcasting)

  • 업 캐스팅은 자식 객체 가 부모 클래스 객체 로 형변환 되는 객체 형변환의 한 유형입니다 .
  • Upcasting을 사용하면 부모 클래스의 변수와 메서드를 자식 클래스로 쉽게 접근할 수 있습니다.
    • 여기에서는 모든 변수와 메서드에 액세스하지 않습니다.
    • 자식 클래스의 일부 지정된 변수와 메서드에만 액세스합니다.
  • 업캐스팅 은 일반화 및 확대 라고도 합니다.
class  Parent{  
   void PrintData() {  
      System.out.println("method of parent class");  
   }  
}  
  
class Child extends Parent {  
   void PrintData() {  
      System.out.println("method of child class");  
   }  
}  
class UpcastingExample{  
   public static void main(String args[]) {  
        
      Parent obj1 = (Parent) new Child();  
      Parent obj2 = (Parent) new Child();   
      obj1.PrintData();  
      obj2.PrintData();  
   }  
}  
결과값
method of child class
method of child class

다운캐스팅 (Downcasting)

  • 업캐스팅 은 또 다른 유형의 객체 유형 캐스팅입니다. Upcasting에서는 부모 클래스 참조 객체를 자식 클래스에 할당합니다.
  • Java에서는 부모 클래스 참조 객체를 자식 클래스에 할당할 수 없지만 다운캐스팅을 수행하면 컴파일 타임 오류가 발생하지 않습니다. 그러나 실행하면 “ClassCastException” 이 발생 합니다.
  • 이제 요점은 Java에서 다운캐스팅이 가능하지 않은 경우 컴파일러에서 이를 허용하는 이유는 무엇입니까? Java에서 일부 시나리오에서는 다운캐스팅을 수행할 수 있습니다. 여기에서 하위 클래스 객체는 상위 클래스에 의해 참조됩니다.
//Parent class  
class Parent {   
    String name;   
    
    // A method which prints the data of the parent class   
    void showMessage()   
    {   
        System.out.println("Parent method is called");   
    }   
}   
    
// Child class   
class Child extends Parent {   
    int age;   
    
    // Performing overriding  
    @Override  
    void showMessage()   
    {   
        System.out.println("Child method is called");   
    }   
}   
    
public class Downcasting{  
    
    public static void main(String[] args)   
    {   
        Parent p = new Child();  
        p.name = "Shubham";  
          
        // Performing Downcasting Implicitly   
        //Child c = new Parent(); // it gives compile-time error   
          
        // Performing Downcasting Explicitly   
        Child c = (Child)p;   
    
        c.age = 18;   
        System.out.println(c.name);   
        System.out.println(c.age);   
        c.showMessage();   
    }   
}  
  • 결과
Shubham
18
Child method is called

업캐스팅과 다운캐스팅이 필요한 이유는 무엇입니까?

Java에서는 Upcasting 을 거의 사용하지 않습니다 . 부모 클래스만 처리하는 코드를 개발해야 할 때 사용합니다. 다운캐스팅 은 자식 클래스의 동작에 액세스하는 코드를 개발해야 할 때 사용됩니다.

// Parent class
class Parent {
    String name;
 
    // A method which prints the
    // signature of the parent class
    void method()
    {
        System.out.println("Method from Parent");
    }
}
 
// Child class
class Child extends Parent {
    int id;
 
    // Overriding the parent method
    // to print the signature of the
    // child class
    @Override void method()
    {
        System.out.println("Method from Child");
    }
}
 
// Demo class to see the difference
// between upcasting and downcasting
public class GFG {
 
    // Driver code
    public static void main(String[] args)
    {
        // Upcasting
        Parent p = new Child();
        p.name = "GeeksforGeeks";
 
        //Printing the parentclass name
        System.out.println(p.name);
        //parent class method is overriden method hence this will be executed
        p.method();
 
        // Trying to Downcasting Implicitly
        // Child c = new Parent(); - > compile time error
 
        // Downcasting Explicitly
        Child c = (Child)p;
 
        c.id = 1;
        System.out.println(c.name);
        System.out.println(c.id);
        c.method();
    }
}
  • Output
GeeksforGeeks
Method from Child
GeeksforGeeks
1
Method from Child

image

참고

  • https://www.bogotobogo.com/cplusplus/upcasting_downcasting.php
  • 여러군데에서 짜집기…