1

次のコードの出力は何ですか?

class A {
    public int data=5;
    private int pd = 6;

    public void print() {
        System.out.println(data+pd);
        f();
    }

    protected void f() {
        System.out.println(“A::f()”);
    }
}

class B extends A {
    public int data=2;
    private int pd = 3;

    public void print() {
        super.print();
        System.out.println(data+pd);
    } 

    protected void f() {
        System.out.println(“B::f()”);
    }
}

public class TestAB {
    public static void main(String[] args) {
        A a = new B();
        a.print();
        System.out.println(a.data);
    }
}

出力は次のとおりです。

11
B::f()
5
5

私が知っているのは、オブジェクトaがクラスBであるということだけです。しかし、以下の詳細は非常に紛らわしいです...ベースクラスと継承クラスで定義された同じ変数で何が起こっているのか誰かが説明できますか?どのprint() 'またはprint() 'が呼び出されますか?

お時間をいただきありがとうございます。

4

2 に答える 2

2

を呼び出すとa.print();、 の印刷関数class Bが呼び出されます。あなたがそれを明確にしていることを願っています(ポリモーフィズム)。B クラスの print() メソッドでは、super.print()が呼び出され、次にメソッド が呼び出されますf()。再びポリモーフィズムの原則で、クラス B の f()メソッドが呼び出されます。

ポリモーフィズムは関数に対してのみ機能します。したがってSystem.out.println(a.data);、メイン関数では、 2 ではなく 5 でA classある変数を出力するだけです。これを理解していただければ幸いです。

このリンクを参照してください:

http://www.coderanch.com/t/392179/java/java/Polymorphism-data-members

于 2013-01-19T07:31:00.770 に答える
0

「クローンについて」

さて、あなたは大きな間違いのために理解できません:クラスBはA拡張クラスです。つまり、最初はクラスaがあり、それ以上のものはありません。

自分のクローンを想像してみてください。次に何をすべきかについて多くの指示はありませんが、できるようにすでに歩いたり寝たりすることはできますが、話すことができず、ピアノの食べ方や演奏方法もわかりません。したがって、このかわいそうな男は自分自身のために非常に長く存在することはありませんが、あなたは自分が何をしているのかを知っていました。2つ目は、食べたり、飲んだり、その他多くの面白いことをすることができますが、話すことはできません。したがって、他に1つ、2つ、および3つ作成します。友達と話すことができ、餌を与えられずにその人生を生きることができて幸せです。次はすべての作業を行うことであり、最後はライトをオンにします。

最初のことを考えてみましょう。あなたは愚かなクローンを作成しましたが、それは2つの機能を持っていました-歩くことと眠ることです。それは先駆的な状態であるため、彼をクローンAと呼ぶことも、クラスAクローンと呼ぶこともできます。

次のクローン作成操作中に、成功したクラスBクローンを作成しました。これは、主に2つの新しい強み、つまり食べることと飲むことによって、クラスAのクローンを拡張します。これを実行できるようにするために、クラスBクローンの経路探索システムに冷蔵庫とバーの場所に関する情報も追加しました。そのため、クラスAクローンのウォーキングDNAを上書きする必要がありました。これはどのように見えるでしょうか?


最初のクローン:

class CloneA
{
    void walk()
    {
        Position p = getRandomPosition();
        walkTo( p );
    };
    void sleep()
    {
        sleepy = sleepy - 1;
    }
    void main()
    {
        if ( itIsLate() )
            sleep();
        else
            walk();
    }
}

そのメインプログラムは、いつスリープするか、いつ歩き回るべきかをクローンに制御します。getRandomPosition()、walkTo(Position)、itIsLate()の3つの既知のメソッドを使用しています。あなたはあなたの古い電話でこの実用的なものを見つけて、それをクローンに与えました。たとえば、クラスBのクローンを見てみましょう。CloneBには、主にさらに2つの能力があります。

void drink();
void eat();

以前に計画したように、完全に新しいクローンを作成する必要はありません。すでに完全な親があります。これは、その知識のすべてを新しいものに継承します。あとは、歩く方法を変更するだけです。そうしないと、現在処理できるアイテムをどこで入手できるかがわかりません。


したがって、2番目の構造は次のようになります。

class CloneB extends CloneA
{
    void drink() { thursty = thursty - 1; }
    void eat()   { hungry  = hungry  - 1; }

    @Override
    void walk()
    {
        if ( itIsEary() || itIsLate() )
        {
            Position fp = fridgePosition;
            walkTo( fp );
            eat();
            Position bp = barPosition;
            walkTo( bp );
            drink();
        }
        else
            super.walk();
    }
}

CloneBは、移動する新しいポジションを検索するたびに、時間をチェックするようになりました。遅い時間または(||)早い時間を認識すると、冷蔵庫とバーの位置を記憶し、次々と歩き始め、食べたり飲んだりし、時間になるとwalk()を呼び出します。 super.walk()による親CloneAの指示。それはあなたにとって良いことです、あなたは同じコマンドを二度与える必要はありません。

この2つの生き物を見ると、いくつかの違いがわかりますが、それらの特徴のほとんどは同じです。たぶん、あなたはすでにCloneBが本当にCloneAであることを考えていたでしょう。CloneAをCloneAにする識別子もCloneBに継承されます。さらに-CloneBはそれ自体を処理できます!悲しいことに、CloneAがCloneBになることは決してありません。

ここで、両方を使用して次の簡単なテストを行う場合は、オブジェクト指向言語の主要なルールの1つを理解する必要があります。

  • 両方のクローンをドアが1つしかない小さな部屋に入れます。
  • 紙にCloneAという名前を書いて、ドアに貼り付けます。
  • 紙に書かれた名前の由来である楽園への扉に入ることができるのは、これらのクローンだけであることをクローンに伝えてください。
  • 楽園に行き、実験を数回再試行してください。しばらくすると、確実になります。CloneAまたはCloneBが表示される可能性は50%です。どちらも未知のオブジェクトを見つける方法が同じであり、どちらもCloneAのように感じられるため、純粋にランダムです。あなたは今、別の不利益を被っています。両方のクローンは同じように見えますが、現時点でわかっているのは、入力されたクローンがCloneAの属性を持っている必要があるということだけです。
  • 翌日また来て、ドアに貼ってある紙にCloneBの名前を書いてください。了解しました。CloneAは、正直なクローンである場合、ドアを通過することはありません。あなたは確信することができます。これはCloneBです。

Javaでもまったく同じです。クローンのインスタンス。これらのcAとcBに同じように名前を付けましょう。

CloneA cA = new CloneA();
CloneB cB = new CloneB();

// assign cloneB instance to cloneA instance:
cA = cB;

// error by default:
cB = cA;

あなたが書いたサンプルが示されているように、あなたは以下を行うこともできます(パラダイスメソッド):

CloneA cA = new CloneB();

短所:現時点では、cAは確かにCloneBですが、CloneBに特定の指示を与えたい場合、これは不可能または安全ではありません。あなたが休暇中にそれがもう生きているかどうか誰が知っていますか?

しかし、あなたはその時無力ではありません。クローンにその継承について尋ねることができます。また、ここでは、彼らがあなたに伝えることができないか、単に間違った情報を提供している可能性があります。彼らが何ができるかを知ってから、彼らがあなたが彼らに求めたものであるかどうかを彼らに尋ねることはしばしば有利です。その後、CloneBであるため、CloneAインスタンスに確実に話しかけることができます。例えば:

CloneA cA = new CloneB();

if ( cA instanceof CloneB )
    ( CloneB ) cA.eat();

もう彼らと交流したくないのなら、気にしないでください。cAのインスタンスは、新しいCloneB情報で上書きされており、彼が正確に誰であるかを知っている場合は、独立して食べたり飲んだりします。最後のコードスニプレットで行ったことは、型キャストと呼ばれます。同じことを行うための別の通常の方法は次のとおりです。

CloneB.class.cast( cA ).eat();

// or storing in a new variable for an easier later handling
CloneB cB = CloneB.class.cast( cA );

今、私たちはほとんど最後の3つの実用的なクローンを忘れました。ただし、すべてのクローンには、拡張するメソッドが1つしかありません。クローン文明をどのように計画しているかは私にはわかりません。Javaは、ほとんどの場合、同じことを行うための豊富な代替方法を提供します。簡単にするために、CloneBのクローンを3回作成したとします。これらの3つのクローンのタスクは、組み合わせるにはあまりにも異なります。彼らの最初の誕生日に、あなたは彼らに歴史的プレゼントを与えるでしょう-彼らの最初の家族の木:

                     TalkerClone
                  /
CloneA  -  CloneB  -  WorkerClone
                  \
                     LightSwitchClone

だから今、彼らに教え始めてください:あなたの誰もが他に類を見ないです、しかしあなたの中ですべてはCloneBと(Grand-)CloneAの一部です...

最後に、私はあなたの質問を忘れてはなりません。たぶんあなたは今あなた自身のためにそれに答えることができますが、完全性のために:

class A {
    public int data=5;                // 13.
    private int pd = 6;

    public void print() {             // 6.
        System.out.println(data+pd);  // 7. ( output "11" )
        f();                          // 8.
    }

    protected void f() {
        System.out.println(“A::f()”);
    }
}

class B extends A {                   // 2.
    public int data=2;
    private int pd = 3;

    public void print() {             // 4.
        super.print();                // 5.
        System.out.println(data+pd);  // 11. ( output 5 )
    } 

    protected void f() {               // 9.
        System.out.println(“B::f()”);  // 10. ( output "B::f()" )
    }
}

public class TestAB {
    public static void main(String[] args) {
        A a = new B();               // Command A; 1.
        a.print();                   // Command B; 3.
        System.out.println(a.data);  // Command C; 12. ( output 5, 2nd )
    }
}

コマンドC、12番目がどこから来ているのかわからない場合は、パラダイス実験をもう一度行ってください。

アプリケーションで継承をより便利にするために、モディファイア(パブリック、プロテクトなど)について自分自身に通知することをお勧めします。

頑張って、あなたのクローンをたくさん楽しんでください:)

于 2013-01-19T10:17:13.443 に答える