ホームページ >Java >&#&チュートリアル >Java の上方変換と下方変換の使い方の紹介 (コード付き)

Java の上方変換と下方変換の使い方の紹介 (コード付き)

不言
不言転載
2019-03-19 09:35:073533ブラウズ

この記事は、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 を実行すると、出力はスーパークラスですか、それとも子クラスですか?当初期待していたスーパークラスではなく、チルドレンクラスです。これは、 a が実際にはサブクラス オブジェクトを指しているためです。もちろん、心配する必要はありません。Java 仮想マシンは、どの特定のメソッドを呼び出す必要があるかを自動的かつ正確に識別します。ただし、上方変換により、オブジェクトは 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

実際には、a2 の下向き変換コードの後は B b2 = (B) になります。コメントには、実行時エラーが発生することがすでに示されています。最初の文の下向き変換コードはOKなのに、2番目の文のコードが間違っているのはなぜですか?これは、a1 がサブクラス B のオブジェクトを指しているためで、当然、サブクラス B のインスタンス オブジェクト b1 も a1 を指すことができます。また、a2 は親クラス オブジェクトであり、サブクラス オブジェクト b2 は親クラス オブジェクト a2 を指すことはできません。では、ダウンキャスト実行時のランタイム ClassCastException を回避するにはどうすればよいでしょうか?セクション5.7.7で学習したinstanceofを使用するだけです。クラス C のコードを修正してみましょう。

A a2 = new A();

if (a2 instanceof B) {

B b2 = (B) a2;

b2.aMthod();

b2.bMethod1();

b2.bMethod2();

}

このように処理すると、型変換時に ClassCastException が発生することを気にする必要がなくなります。

以上がJava の上方変換と下方変換の使い方の紹介 (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。