次のようなコードがあります。
class Hello {
class Thing {
public int size;
Thing() {
size = 0;
}
}
public static void main(String[] args) {
Thing thing1 = new Thing();
System.out.println("Hello, World!");
}
}
私はThing
が何もしないことを知っていますが、私のHello、Worldプログラムはそれなしでうまくコンパイルできます。私に失敗しているのは私の定義済みクラスだけです。
そしてそれはコンパイルを拒否します。新しいThingを作成した行にNo enclosing instance of type Hello is accessible."
が表示されます。私はどちらかと思います:
何か案は?
static class Thing
はあなたのプログラムを動かします。
Thing
を内部クラスとして持っています。これは(定義上はHello
の特定のインスタンスに関連付けられています(これを使用または参照していない場合でも))。つまり、new Thing();
を指定せずに言うとエラーになります。スコープ内の特定のHello
インスタンス.
代わりにそれを静的クラスとして宣言した場合、それは "ネストされた"クラスです。これは特定のHello
インスタンスを必要としません。
クラスThing
を非静的な内部クラスとして宣言しました。それはそれがHello
クラスのインスタンスと関連付けられなければならないことを意味します。
あなたのコードでは、静的コンテキストからThing
のインスタンスを作成しようとしています。それがコンパイラが不平を言っていることです。
いくつかの解決策があります。どのソリューションを使用するかは、達成したいことによって異なります。
Thing
をHello
クラスから移動します。
Thing
をstatic
ネストクラスに変更します。
static class Thing
Hello
のインスタンスを作成する前に、Thing
のインスタンスを作成します。
public static void main(String[] args)
{
Hello h = new Hello();
Thing thing1 = h.new Thing(); // hope this syntax is right, typing on the fly :P
}
意味のあるThing
のインスタンスがHello
のインスタンスに依存している場合、最後の解決策(non-staticネストクラス)は必須です。たとえば、次のようになります。
public class Hello {
public int enormous;
public Hello(int n) {
enormous = n;
}
public class Thing {
public int size;
public Thing(int m) {
if (m > enormous)
size = enormous;
else
size = m;
}
}
...
}
次のように、クラスThing
のオブジェクトを作成しようとする生の試み
Thing t = new Thing(31);
それに対して31をテストするための明白なenormous
値がないので、問題があるでしょう。このh.enormous
値を提供するには、h
外部クラスのインスタンスHello
が必要です。
...
Hello h = new Hello(30);
...
Thing t = h.new Thing(31);
...
Thing
がなければHello
を意味しないからです。
入れ子/内部クラスの詳細については、 入れ子クラス(The Java Tutorials)
うーん...とても良い答えがたくさんありますが、もっと追加したいと思います。 Java-Javaの内部クラスを簡単に見れば、クラスを別のクラス内に定義することができます。このようにクラスを入れ子にできることには、いくつかの利点があります。
他のクラスのクラスをhide(カプセル化を強化)することができます - そのクラスがそのクラスに含まれるクラスによってのみ使用されている場合は特に重要です。この場合、外の世界がそれについて知る必要はありません。
クラスは必要に応じて論理的にグループ化されているため、コードを保守しやすいにすることができます。
内部クラスは、それを含むクラスのインスタンス変数とメソッドへのaccessを持ちます。
主に3種類のInner Classes
覚えておくべき重要な点のいくつか
上記の概念を実際に見てみましょう。
public class MyInnerClass {
public static void main(String args[]) throws InterruptedException {
// direct access to inner class method
new MyInnerClass.StaticInnerClass().staticInnerClassMethod();
// static inner class reference object
StaticInnerClass staticInnerclass = new StaticInnerClass();
staticInnerclass.staticInnerClassMethod();
// access local inner class
LocalInnerClass localInnerClass = new MyInnerClass().new LocalInnerClass();
localInnerClass.localInnerClassMethod();
/*
* Pay attention to the opening curly braces and the fact that there's a
* semicolon at the very end, once the anonymous class is created:
*/
/*
AnonymousClass anonymousClass = new AnonymousClass() {
// your code goes here...
};*/
}
// static inner class
static class StaticInnerClass {
public void staticInnerClassMethod() {
System.out.println("Hay... from Static Inner class!");
}
}
// local inner class
class LocalInnerClass {
public void localInnerClassMethod() {
System.out.println("Hay... from local Inner class!");
}
}
}
これが皆さんに役立つことを願っています。詳しくは を参照してください
次の簡単な例でそれを理解しましょう。これはNON-STATIC INNER CLASSであるために起こります。あなたは外のクラスのインスタンスが必要です。
public class PQ {
public static void main(String[] args) {
// create dog object here
Dog dog = new PQ().new Dog();
//OR
PQ pq = new PQ();
Dog dog1 = pq.new Dog();
}
abstract class Animal {
abstract void checkup();
}
class Dog extends Animal {
@Override
void checkup() {
System.out.println("Dog checkup");
}
}
class Cat extends Animal {
@Override
void checkup() {
System.out.println("Cat Checkup");
}
}
}