Diceクラスを継承することなくRandomクラスを利用してサイコロを実装する方法

このQ&Aのポイント
  • JavaのDiceクラスは、Randomクラスを継承してサイコロの役割を果たします。しかし、DiceクラスはRandomクラスのnextIntメソッド以外はUnsupportedOperationExceptionをスローしており、相続の拒否しているため実装方法としては適切ではありません。
  • 代わりに、Randomクラスを継承するのではなく、委譲を使用してDiceクラスを実装することができます。これにより、Randomクラスのすべてのメソッドが利用可能になり、サイコロの役割を正しく果たすことができます。
  • Mainクラスでは、Diceクラスのインスタンスを2つ生成し、10回ずつサイコロを振った結果をコンソールに出力しています。このようにDiceクラスを正しく実装することで、サイコロの振る舞いを再現することができます。
回答を見る
  • ベストアンサー

回答が分かりません。どなたかお助けを。

以下のように Dice クラスがあります。このクラスはサイコロの役目をします。 サイコロの目は Random クラスを継承して擬似乱数を生成しています。 Main クラスでは、Dice インスタンスを2つ生成してサイコロを10回振った結果を コンソールに出力します。 しかし、Dice クラスは Random クラスの nextInt メソッド以外は UnsupportedOperationException をスローして使用していません。 つまり、相続の拒否しているので継承を使用すべき実装ではありません。 Random クラスを継承ではなく委譲を使用した実装に変更してください。 import java.util.*; public class Dice extends Random { // コンストラクタ public Dice() { super(314159L); } public Dice(long seed) { super(seed); } @Override public int nextInt() { // サイの目は最大6で、返される値は0~5なので+1した値を返す。 return nextInt(6) + 1; } @Override public void nextBytes(byte[] bytes) { throw new UnsupportedOperationException(); } @Override public long nextLong() { throw new UnsupportedOperationException(); } @Override public boolean nextBoolean() { throw new UnsupportedOperationException(); } @Override public float nextFloat() { throw new UnsupportedOperationException(); } @Override public double nextDouble() { throw new UnsupportedOperationException(); } @Override public double nextGaussian() { throw new UnsupportedOperationException(); } } public class Main { public static void main(String[] args) { Dice dice01 = new Dice(); Dice dice02 = new Dice(456L); executeDice(dice01); executeDice(dice02); } private static void executeDice(Dice dice) { // サイコロを10回振ります。 for (int i = 0; i < 10; i++) { System.out.printf("%d, ", dice.nextInt()); } System.out.println(); } }

  • Java
  • 回答数2
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • hofchan
  • ベストアンサー率62% (17/27)
回答No.2

// java.util.Random への参照を持つ // Dice と書いていたのは Random に訂正させてください  private Rabdom rand = new Random();  public int nextInt() {   return rand.nextInt(6) + 1;  } -------------------------------------------------- >>>は、全体的にどの様に記述すればいいのですか? 何かの課題のようですね、ですのでヒントだけです @Override public int nextInt() { // サイの目は最大6で、返される値は0~5なので+1した値を返す。 return nextInt(6) + 1; } 元のコードはこれですよね、これは自分自身で 1~6 の乱数を発生させる 処理をしていますが下記コードでは public class Dice {  private Random rand = new Random();  public int nextInt() {   return rand.nextInt(6) + 1;  } 実質は Random インスタンスでの処理ですよね この様な実装にして Main クラスから同じように動けば 問題ないかと思います

yuminose
質問者

お礼

回答くれた方々ありがとうございます。 まだまだ初心者なので、ちょくちょく質問など書き込む機会が あると思います。 よろしくお願いします。

その他の回答 (1)

  • hofchan
  • ベストアンサー率62% (17/27)
回答No.1

// java.util.Random への参照を持つ  private Dice rand = new Random();  public int nextInt() {   return rand.nextInt(6) + 1;  }

yuminose
質問者

補足

すみません。質問した者です。 下記の // java.util.Random への参照を持つ  private Dice rand = new Random();  public int nextInt() {   return rand.nextInt(6) + 1;  } は、全体的にどの様に記述すればいいのですか? (どの様に記述し直せばいいのでしょうか。)

関連するQ&A

  • ランダム

    次のプログラムで同じ数字を出ないようにするにはどうすれば良いでしょうか。 import java.util.*; class RandomNum { public static void main(String args[]) { Random numRandom = new Random(); for (int i = 1; i <= 5; i++) { System.out.println(numRandom.nextInt(10)); } } }

    • ベストアンサー
    • Java
  • C#のarrayに別のclassを挿入したのですが・・・

    失礼します。 サイコロを転がすために2つのclassを作り、片方は サイコロ用のコンストラクターなどをコーディングして もう1つにMain methodを挿入しました。 とりあえず、サイコロを1つではなく、5つほど転がすという プログラムにしたいので、 private Dice[] dice = new Dice[5]; (ここでのDiceはDice.csの中のコンストラクターです。) として、とりあえず、サイコロを5つ分、確保したのですが、 特定のサイコロの呼び出し方が分かりません。 int diceA = dice[3].Dice();でもなく、 int diceA = Dice[3]でも動かず、 多分、基本的な考え方が間違っているのかも知れませんが、 例えば、4番目のサイコロの値を呼び出す場合、 どのように書けば、それだけを呼び出せるのでしょうか? またfor(int i=0; i>5; i++){ Dice[i] =dice[i].Roll??? } などのように自動的に5つのサイコロに値を振り分けることは 可能なのでしょうか?(RollはDice内にある、 ランダムメソッドです。dice[]の考え方自体が違って いるためか、この方法ではエラーになってしまいます。) まだプログラミング自体を始めて程ないものですので、 詳しく教えて頂けると嬉しく思います。 お願いします。

  • Randomクラスを使い同じ値をもつことがないように

    するには? サンプルコードをどう改良したらいいですか 例えば{1,3,5,5,3,2}の連続した5とならないようにするには? import java.util.*; class Sample6_9{ public static void main(String args[]){ Scanner std = new Scanner(System.in); Random rand = new Random(); System.out.print("要素数:"); int n = std.nextInt(); int[]a = new int[n]; for(int i=0;i<n;i++){ a[i] = 1+rand.nextInt(10); System.out.println("a["+i+"]="+a[i]); } } }

  • 変数を取得したい

    例えば、次のようなプログラムで1個の乱数を取得します。その取得した乱数の一番下の桁の数字(0~9)だけに着目し、変数iなどに値を取得するといったことは出来ますでしょうか? import java.util.*; public class RandomTest { public static void main(String[] args) { Random generator = new Random(); for(int i=0; i<1; i++){ int ran = generator.nextInt(); System.out.println(ran); } } }

    • ベストアンサー
    • Java
  • virtual時のoverrideとnewの違い

    C#で、 virtualがない時はnewしか使えませんが、 virtualがある時はoverrideとnewが使えますが、 overrideとnewを使った時の違いがよく分かりません。 例えば、基本クラスに public virtual void show(){  Console.WriteLine("基本クラス"); } というメソッドがあるとして、 派生クラスで、 public override void show(){  Console.WriteLine("派生クラス"); } とすると、 基本クラスのメソッドが上書きされて、 Console.WriteLine("派生クラス"); が実行されますが、 派生クラスで、 public new void show(){  Console.WriteLine("派生クラス"); } とした場合にも、 基本クラスのメソッドが隠匿されて、 Console.WriteLine("派生クラス"); だけが実行されます。 virtual使用時において、 継承メソッドの隠匿(new)と、 継承メソッドの上書き(override)では、 一見、なにも違いがないように見えるのですが、 何か違うのでしょうか。

  • 乱数を発生させて、それを配列して小さい順に並べる

    乱数の発生のさせ方は、質問集で見て import java.util.Random; class ransuu { public static void main(String args[]) { Random rand = new Random(); for ( int i = 0; i <10; i++){ int x = rand.nextInt(9); System.out.println(x); } } } を用いて表示できたのですが、そのあとの配列がよく分かりませんのでぜひ教えてください。ちなみに私の持っているテキストには任意の数(22、80、57、60、50など)を並べ替えるというものはあるのですが、今回のような乱数+配列の例が載っていないのでよく分かりませんでした。

    • ベストアンサー
    • Java
  • iアプリ/サイコロの作り方

    Doja5.1 J2SDK1.4.2 を使ってソースを書いています。 まずサイコロを振るプログラムを作って、そのあとサイコロの数字を画像で表示できるようなものを作りたいです。 サイコロの画像はgifで用意してあります。 まずサイコロを振るプログラムですが以下のように書きました。 しかし、エラーが出ないにも関わらずエミュレータで動きません。 どこが間違っているのかどなたか教えてください。 また、画像を表示するほうのプログラムはどこを変えれば良いでしょうか。 よろしくお願い致します。 import com.nttdocomo.ui.*; import java.util.Random; class MainCanvas extends Canvas { int dice[] = new int[8*2]; Random rnd = new Random(); boolean init_flg = false; public MainCanvas() { setSoftLabel(Frame.SOFT_KEY_1,"サイコロ"); setSoftLabel(Frame.SOFT_KEY_2,"終了"); } public void paint( Graphics g ) { if(init_flg == false) { init_flg = true; return; } g.clearRect(0,0,200,2*8*13+30); int i; for(i=0;i<8*2;i++) { g.drawString(Integer.toString(i+1)+"回目のサイコロ",0,i*13+30); g.drawString(Integer.toString(dice[i]),100,i*13+30); } } public void processEvent( int type, int param ) { if( type == Display.KEY_PRESSED_EVENT ) { if( param == Display.KEY_SOFT1 ) { int i; for(i=0;i<8*2;i++) { dice[i] = rnd.nextInt(11)+2; } repaint(); } else if( param == Display.KEY_SOFT2 ) { IApplication.getCurrentApp().terminate(); } }

    • ベストアンサー
    • Java
  • c# この高速化の方法あり? 2

     こんにちは、c#初心者です。  現在ライブラリを作成しているのですが、その中でちょっと問題がありそうな高速化の方法を思いついたので質問させていただきました。  継承させるクラスを作るときに、継承予定のクラスで実装するメソッドやメンバを、基のクラスでは public class Class1 {   internal virtual void Method()   {     throw new NotImplementedException();   } } // - - - - - - - - - - - - - - - - - - - - - - - - - public class Class2 {   internal override void Method()   {     //ここで実装   } } として、 このオブジェクト「sampleObj」があったとして、 if ( sampleObj is Class2 )   sampleObj.Method(); のようにすることで Class2 temp = sampleObj as Class2; if ( temp != null )   temp.Method(); や if ( sampleObj is Class2 )   ((Class2)sampleObj).Method(); のようにすることよりも若干高速になるようです。  末端のアプリケーションならまだ問題になりにくいかもしれませんが、今回はライブラリということなので気になっています。  気休め程度に「internal」になっていますがそれでもまずい気がします。  どなたか詳しい方がいらっしゃいましたら教えていただけませんか?

  • 配列に値を入れて表示させたいが

    import java.util.*; class Sample{ public static void main(String args[]){ Scanner std = new Scanner(System.in); System.out.print("クラス数:"); int n = std.nextInt(); int[][]a = new int[n][]; System.out.print("1組の人数");    int m = std.nextInt(); for(int i=0;i<m;i++){ a[i] = std.nextInt(); //ここの部分でコンパイルエラー    System.out.println("(i+1)"+"組"+(i+1)+"番目の点数"+a[i]);   } } } 互換性のない型?と出ますなぜでしょう

    • ベストアンサー
    • Java
  • dokojavaでシンボルerrorがでます。

    -------------------------------------isbn978-4-8443-3638-9 public class Main { public static void main(String[] args){ System.out.println("運勢"); int fortune = new java.util.Random() .nextInt(4) + l; if (fortune == 1) { System.out.println("大吉"); } else if (fortune == 2){ System.out.println("中吉"); } else if (fortune == 3){ System.out.println("吉"); } else{System.out.println("凶"); } } } ----------------------------------- int fortune = new java.util.Random() .nextInt(4) + l; ↑の最後の「l;」がみつかりませんとシンボルerrorになります。