4
public class Program {

    public static void main(String[] args) {
        Listener listener = new Listener();
        listener.listen();
    }
}

public class Listener {

    ServerQuery query;
    int test = 1;

    public listen() {
        query = new ServerQuery();
        Channel ch = new Channel();
        ch.dupa();
    }
}

public class Channel extends Listener {

    public dupa() {
        System.out.print(test); // works fine 
        super.query.doSomething(); // null pointer
        query.doSomething(); //  null pointer
    }
}

I cant access variable "query" in class "Channel". Can anyone explain me why ?

4

5 に答える 5

3

スーパータイプとサブタイプの概念を誤解しています。

直接の問題は、クエリ変数を使用する前にインスタンス化する必要があることです。

呼び出すch.listen()前に呼び出すdupaか、内部で呼び出しますdupa

ここでの主な問題は、サブタイプとスーパータイプの関係を理解することです。

あなたの Channel オブジェクトは のインスタンスへの参照を持っていませんListener 。それは単なるサブタイプです。したがって、クラスのフィールドにアクセスするなど、スーパータイプのフィールドにアクセスする必要がある場合は、使用する前にインスタンス化する必要があります。

Listener 内で Channel オブジェクトを作成するロジックはありません。チャネルはリスナーなので、代わりに作成できます。

ここか他の場所でそれについてもっと読むことをお勧めします。

コードには、次のものを使用できます。

public class Program {

    public static void main(String[] args) {
        Channel ch = new Channel();
        ch.listen(); // will instantiate ch.query
        ch.dupa(); 
    }
}
public class Listener {

    ServerQuery query;
    int test = 1;

    public listen() {
        query = new ServerQuery();
    }
}

public class Channel extends Listener {

    public dupa() {
        System.out.print(test);
        super.query.doSomething();
        query.doSomething();
    }
}
于 2013-03-05T15:08:47.563 に答える
1

詳細な説明のために編集:

スーパークラスの変数は、サブクラスで実装できるように保護されていると定義する必要があります。スコープを宣言しない場合、フィールドはpackage-privateとして宣言されます。

スコープの詳細については、公式チュートリアルを参照してください。

コードに関するもう1つの注意点:変数はここではインスタンス化されないため、最初queryにメソッドを呼び出さないと、常にNPEが返されます。listen()

于 2013-03-05T15:07:31.140 に答える
0

Channel ch = new Channel();を初期化しませんquery

参照を初期化する呼び出しなしdupa()Channelオブジェクトを呼び出しています。listen()query

于 2013-03-05T15:17:43.783 に答える
0

私はそのようなものを作ることでそれを解決しました:

public class Channel extends Listener {
     ServerQuery queryInstance;
     Listener(ServerQuery listener){
         queryInstance = listener;
     }
     public dupa() {

        System.out.print(test); // works fine 
        super.query.doSomething(); // null pointer
        query.doSomething(); //  null pointer
    }
}
于 2013-03-05T15:17:23.900 に答える
0

2 つの Listener オブジェクトを操作しています。1 つは Channel クラス (Channel.super() など) にあり、もう 1 つはメイン メソッドにあります。

混乱は、 Channel オブジェクトが main メソッドで宣言したのと同じリスナー クラスを使用すると想定していることだと思います。

一言で言えば、答えはクエリ変数が初期化されていないということです。

したがって、主に設計上の問題があります。いくつかの方法で修正できます。簡単な方法の 1 つは、クエリを dupa メソッドに渡し、そのクエリ オブジェクトを利用することです。

于 2013-03-05T15:28:22.160 に答える