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
참고
- https://www.bogotobogo.com/cplusplus/upcasting_downcasting.php
- 여러군데에서 짜집기…