> Java > java지도 시간 > 본문

Java 상향 변환 및 하향 변환 사용 소개(코드 포함)

不言
풀어 주다: 2019-03-19 09:35:07
앞으로
3504명이 탐색했습니다.

이 기사는 Java의 상향 변환 및 하향 변환(코드 포함)에 대한 소개를 제공합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

1 상향 변환(하위 클래스를 상위 클래스로 변환)
예:

package a.b;

public class A {

public void a1() {

       System.out.println("Superclass");

}

}

A的子类B:

package a.b;

public class B extends A {

public void a1() {

       System.out.println("Childrenclass"); //覆盖父类方法

}

       public void b1(){} //B类定义了自己的新方法

}

C类:

package a.b;

public class C {

public static void main(String[] args) {

       A a = new B(); //向上转型

       a.a1();

}

}
로그인 후 복사

C를 실행하면 출력되는 클래스가 Superclass입니까 아니면 Childrenclass입니까? 원래 기대했던 Superclass가 아니라 Childrenclass입니다. 이는 실제로 하위 클래스 객체를 가리키기 때문입니다. 물론 걱정할 필요가 없습니다. Java 가상 머신은 어떤 특정 메소드를 호출해야 하는지 자동으로 정확하게 식별합니다. 그러나 상향 변환으로 인해 a 객체는 b1()과 같은 상위 클래스와 다른 메서드를 잃게 됩니다. 어떤 사람들은 이렇게 물을 수도 있습니다. 이것은 불필요하지 않습니까? 다음과 같이 쓸 수 있습니다:

B a = new B();

a.a1();

그렇죠! 그러나 이는 추상화 지향 프로그래밍 기능을 상실하고 확장성을 감소시킵니다. 실제로 상향 변환을 통해 프로그래밍 작업량도 줄일 수 있습니다. 아래의 모니터 클래스 Monitor를 살펴보겠습니다.

package a.b;

public class Monitor{

public void displayText() {}

public void displayGraphics() {}

}

液晶显示器类LCDMonitor是Monitor的子类:

package a.b;

public class LCDMonitor extends Monitor {

public void displayText() {

       System.out.println("LCD display text");

}

public void displayGraphics() {

       System.out.println("LCD display graphics");

}

}

阴极射线管显示器类CRTMonitor自然也是Monitor的子类:

package a.b;

public class CRTMonitor extends Monitor {

public void displayText() {

       System.out.println("CRT display text");

}

public void displayGraphics() {

       System.out.println("CRT display graphics");

}

}

等离子显示器PlasmaMonitor也是Monitor的子类:

package a.b;

public class PlasmaMonitor extends Monitor {

public void displayText() {

       System.out.println("Plasma display text");

}

public void displayGraphics() {

       System.out.println("Plasma display graphics");

}

}

现在有一个MyMonitor类。假设没有向上转型,MyMonitor类代码如下:

package a.b;

public class MyMonitor {

public static void main(String[] args) {

       run(new LCDMonitor());

       run(new CRTMonitor());

       run(new PlasmaMonitor());

}

public static void run(LCDMonitor monitor) {

       monitor.displayText();

       monitor.displayGraphics();

}

public static void run(CRTMonitor monitor) {

       monitor.displayText();

       monitor.displayGraphics();

}

public static void run(PlasmaMonitor monitor) {

       monitor.displayText();

       monitor.displayGraphics();

}

}

可能你已经意识到上述代码有很多重复代码,而且也不易维护。有了向上转型,代码可以更为简洁:

package a.b;

public class MyMonitor {

public static void main(String[] args) {

       run(new LCDMonitor());                     //向上转型

       run(new CRTMonitor());                     //向上转型

       run(new PlasmaMonitor());            //向上转型

}

public static void run(Monitor monitor) { //父类实例作为参数

       monitor.displayText();

       monitor.displayGraphics();

}

}

我们也可以采用接口的方式,例如:

package a.b;

public interface Monitor {

abstract void displayText();

abstract void displayGraphics();

}

将液晶显示器类LCDMonitor稍作修改:

package a.b;

public class LCDMonitor implements Monitor {

public void displayText() {

       System.out.println("LCD display text");

}

public void displayGraphics() {

       System.out.println("LCD display graphics");

}

}
로그인 후 복사

2 다운캐스트(상위 클래스가 하위 클래스로 변환됨)

A类:

package a.b;

public class A {

void aMthod() {

       System.out.println("A method");

}

}

A的子类B:

package a.b;

public class B extends A {

void bMethod1() {

       System.out.println("B method 1");

}

void bMethod2() {

       System.out.println("B method 2");

}

}

C类:

package a.b;

public class C {

     public static void main(String[] args) {

            A a1 = new B(); // 向上转型

            a1.aMthod();    // 调用父类aMthod(),a1遗失B类方法bMethod1()、bMethod2()

            B b1 = (B) a1; // 向下转型,编译无错误,运行时无错误

            b1.aMthod();    // 调用父类A方法

            b1.bMethod1(); // 调用B类方法

            b1.bMethod2(); // 调用B类方法

            A a2 = new A();

            B b2 = (B) a2; // 向下转型,编译无错误,运行时将出错

            b2.aMthod();

            b2.bMethod1();

            b2.bMethod2();

     }

}

从上面的代码我们可以得出这样一个结论:向下转型需要使用强制转换。运行C程序,控制台将输出:

Exception in thread "main" java.lang.ClassCastException: a.b.A cannot be cast to a.b.B at
                a.b.C.main(C.java:14)

A method

A method

B method 1

B method 2
로그인 후 복사

사실 B b2 = (B) a2에서 다운캐스트 코드 뒤의 주석은 이미 런타임 이벤트가 실수가 발생합니다. 첫 번째 문장의 하향 변환 코드는 괜찮은데 두 번째 문장의 코드는 잘못된 이유는 무엇인가요? 이는 a1이 하위 클래스 B의 개체를 가리키므로 물론 하위 클래스 B의 인스턴스 개체 b1도 a1을 가리킬 수 있기 때문입니다. 그리고 a2는 부모 클래스 객체이고, 하위 클래스 객체 b2는 부모 클래스 객체 a2를 가리킬 수 없습니다. 그렇다면 다운캐스트를 수행할 때 런타임 ClassCastException을 방지하려면 어떻게 해야 합니까? 섹션 5.7.7에서 배운 인스턴스를 사용하세요. C 클래스의 코드를 수정해 보겠습니다.

A a2 = new A();

if (a2 instanceof B) {

B b2 = (B) a2;

b2.aMthod();

b2.bMethod1();

b2.bMethod2();

}
로그인 후 복사

이렇게 처리한 후에는 유형 변환 시 ClassCastException이 발생할 염려가 없습니다.

위 내용은 Java 상향 변환 및 하향 변환 사용 소개(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:segmentfault.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿