2017-11-28 19 views
0

私は一度購入したスパークチャートを使ってJava言語のいくつかを見直そうとしていました。彼らはこの例を与える匿名内部クラスの使用について:匿名の内部クラスの例の妥当性の懸念

Dice rollDice() { 
    return new Dice() { 
     int number = (int)(Math.random() * 6) + 1; 
    }; 
} 

問題は、私はこれがどのように動作するか表示されていない、とコンパイラは別のクラス内のメソッドとしてそれを受け入れることを得ることができない、です。コンパイラは、 "シンボルが見つかりません"というダイへの各参照について不平を言っています。

例を正しく理解していないか、この完全に無効なコードですか?前もって感謝します!

p.s.これが動作するコードであれば、誰かが私にそれをどのように使用できるかの例を教えてくれますか?

編集:私は匿名の内部クラスの構文はこの上記のコードは、スーパークラスのインスタンスを取るメソッドに渡され

new SuperClassName/InterfaceName() { 
// Implement or override methods in superclass or interface 
// Other methods if necessary 
} 

の下に表示、または完全に実装されて 最終的に理にかなって何かを発見しましたインタフェース。たとえば、EventHandlerパラメータを持ち、handle(ActionEvent e)メソッドを実装するクラスを定義していないメソッドです。このようにして

enlargeButton.setOnAction(
    new EventHandler<ActionEvent>() { 
     public void handle(ActionEvent e) { 
      circlePane.enlarge(); 
     } 
    }); 

、それは本当に匿名になります。私は、Javaのチュートリアルで与えられた例が非常に悪いと思う。

+1

Javaに標準のDiceクラスがないため、「シンボルが見つかりません」。その例にはおそらくあなたが私たちに示していない他の部分が含まれています。とにかく、これは、この例を不明瞭にする匿名の内部クラスを使用するのが好ましい方法のようには見えません。 – Pshemo

+0

いいえ、この例には私があなたに見せていない部分はありません。これが私が質問している理由です。私には非常に不明で、私はそれを正しく読んでいないのか、本当にこの例の使用を理解していないのだろうかと思っていました。私は今、彼らの例がゴミだけであると仮定しています。 – bmcentee148

+0

このコードは、たとえば 'class Dice {...}'に配置する場合にコンパイルされます。しかし、この例は、Diceオブジェクトに乱数をラッピングするだけなので、それほど有用ではありません。このようなダイスでは、すべての1-6の数字を返すことはできませんが、この例を少なくとも不明瞭にする1つの数字だけを返すことができます。匿名のクラスについて知りたい場合は、https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.htmlなどの公式チュートリアルを使用することを検討してください。 – Pshemo

答えて

1

あなたの即時の質問にいくつかの答えをあなたはほとんどあなた自身の質問に答えました、あなたはおそらく完全に物事を理解するために、いくつかの完全なチュートリアルやドキュメンテーションを通過することになるでしょうが、ここにあるように見えます。

最初のサンプルコードは、拡張可能なDiceクラスまたはインターフェイスを持つまでコンパイルされません。

class Dicey { 
    interface Dice { 
    } 
    Dice rollDice() { 
     return new Dice() { 
      int number = (int) (Math.random() * 6) + 1; 
     }; 
    } 
    public static void main(String... none) { 
     Dice dice = new Dicey().rollDice(); 
     // dice.number; <-- not available 
    } 
} 

は今、あなたはこれを行うことができますが、容疑者として、これは(いくつかの理由のために)行うには非常に便利なものはありませんが、最大の問題があることである:例として、あなたが得ることができるので、このコードはコンパイルしますこの匿名インスタンスを作成した後は、実際に.numberメンバーにアクセスする方法はありません。

通常、匿名サブクラスにはインターフェイス上にいくつかのメソッドが実装されているため、実際に何かを行うことができます。したがって、たとえば

class HelloAnonymous { 
    interface Hello { 
     String say(); 
    } 

    Hello hello(String world) { 
     return new Hello() { 
      public String say() { 
       return world; 
      } 
     }; 
    } 

    public static void main(String... none) { 
     System.out.println(new HelloAnonymous().hello("world").say()); 
     // prints 'world' 
    } 
} 

は、何かを言うことができる非常に有用なHelloオブジェクトを作成する方法を提供します。これをすべて言っていると、匿名の内部クラスを書くことはかなり古い学校です。なぜなら、機能的なインターフェイスが今ではそれらのニーズをほぼ置き換えているからです。したがって、この例では次のようになります。

class HelloAnonymous { 
    @FunctionalInterface 
    interface Hello { 
     String say(); 
    } 

    // old school 
    Hello hello(String world) { 
     return new Hello() { 
      public String say() { 
       return world; 
      } 
     }; 
    } 

    // with lambda notation 
    Hello alsoHello(String world) { 
     return() -> { 
      return world; 
     }; 
    } 

    public static void main(String... none) { 
     System.out.println(new HelloAnonymous().hello("world").say()); 
     System.out.println(new HelloAnonymous().alsoHello("world").say()); 
    } 
} 
0

私は「ダイス」クラスについて知らないので、私は同じ方法を書くことができませんが、私はそれに似た何かを試してみます。それはコンパイルし、作業はリフレクションを使用して変数 'number'にアクセスできます。私の意見はそれほど有用ではないということです。次は私のコードです:

public class TestClass { 

    public static void main(String a[]){ 
     TestClass aClass = rollDice(); 
     try { 
     System.out.println("value of number : " + aClass.getClass().getDeclaredField("number").getInt(aClass)); 
     } 
     catch (NoSuchFieldException e) { 
     e.printStackTrace(); 
     } 
     catch (IllegalAccessException e) { 
     e.printStackTrace(); 
     } 
    } 

    static TestClass rollDice() { 
     return new TestClass() { 
     int number = (int) (Math.random() * 6) + 1; 
     }; 
    } 
    } 
0

この例は非常に壊れています。その情報源を投げ捨ててください。これを試してみてください:

import java.util.Random; 

public class DieFactory { 
    interface Die { int roll(); } 

    static Die create(long seed) { 
    Random random = new Random(seed); 
    return new Die() { 
     @Override 
     public int roll() { 
     return random.nextInt(6) + 1; 
     }  
    }; 
    } 

    // Now you can roll 2 dice pretty easily. 
    public static void main(String [] args) { 
    DieFactory.Die die1 = DieFactory.create(42);  
    DieFactory.Die die2 = DieFactory.create(24);  
    for (int i = 0; i < 40; i++) { 
     System.out.println(die1.roll() + die2.roll()); 
    } 
    } 
} 

ちなみに、「サイコロ」という単語は、単なる「ダイ」の複数形です。

関連する問題