質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

4304閲覧

Javaのメソッドの一つをランダムに呼び出す

porpora_0316

総合スコア37

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2018/10/18 01:48

編集2018/10/18 01:49

Javaで、複数のメソッドから一つをランダムに呼び出したいです。

slime,Dragon,Devilの中からランダムに取り出して、最終的に『勇者は(10,100,300のどれか)のダメージを受けた!』と表示することは可能ですか?
なお、継承などの練習をしていたので継承していますが、特に意味などはありません。
お願いします。
インデントなど不慣れなので、分かりにくかったら申し訳ありません。

Java

1import java.util.*; 2class Enemy { 3 public static int attack(){ 4 return 100; 5 } 6} 7 8class Slime extends Enemy { 9 public static int attack() { 10 return 10; 11 } 12} 13 14class Dragon extends Enemy { 15 public static int attack() { 16 return 100; 17 } 18} 19 20class Devil extends Enemy { 21 public static int attack() { 22 return 300; 23 } 24} 25 26public class Main { 27 public static void main(String[] args) { 28 Slime slime = new Slime(); 29 Dragon dragon = new Dragon(); 30 Devil devil = new Devil(); 31 ArrayList<String> teki = new ArrayList<String>(); 32 teki.add("slime"); 33 teki.add("dragon"); 34 teki.add("devil"); 35 int Rand = (int)(Math.random()*3); 36 37 String moji = teki.get(Rand); 38 System.out.println("勇者は" + moji.attack() + "のダメージを受けた!"); 39 40 } 41}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

意味がないとおっしゃってる継承ですが、それを生かしてください。
ListをEnemy型で宣言して、各敵のオブジェクトを入れます。

java

1public class Main { 2 public static void main(String[] args) { 3 Slime slime = new Slime(); 4 Dragon dragon = new Dragon(); 5 Devil devil = new Devil(); 6 ArrayList<Enemy> teki = new ArrayList<>(); 7 teki.add(slime); 8 teki.add(dragon); 9 teki.add(devil); 10 int Rand = (int)(Math.random()*3); 11 12 Enemy selected = teki.get(Rand); 13 System.out.println("勇者は" + selected.attack() + "のダメージを受けた!"); 14 15 } 16}

投稿2018/10/18 02:29

編集2018/10/18 02:54
swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

porpora_0316

2018/10/18 02:48

Mainメソッドをこの通りにしてみたのですが、selectedの中身は『Devil@39a054a5』『Slime@39a054a5』『Dragon@39a054a5』と変わっているのにも関わらず表記は『勇者は100のダメージを受けた!』になってしまいます。
momon-ga

2018/10/18 02:53

attack()は、staticメソッドなので、オーバーライドされません。
swordone

2018/10/24 02:19 編集

では、Enemyクラスとその子クラス全てからstaticを消してください。
porpora_0316

2018/10/18 02:59

ありがとうございます。無事に出来ました。 まだオブジェクト指向を勉強し始めたばかりなので、staticの意味やオーバーライドについて詳しく知りませんでした。 もっと勉強します。
guest

0

これ、コンパイル通ります?
あまりJavaはやっていないですが、コンパイル通らない気が...
String moji = ...;
... moji.attack() ...
っておかしくないですか? そのまま読むと
Stringのattackメソッドを呼び出す です。 String::attack() なんてありましたっけ?

また、コンパイルエラーになるかどうかわかりません ( 試したことないから ) が、
なぜ Enemyを継承しているのにそれぞれ attackメソッドをstaticでやっているんでしょうか?
それなら継承しないほうがいいと思いますが。(強みが薄れる。)


私なら Enemyをそれぞれ継承して Enemyの配列かリストを用意する。

その前に、Enemyクラスやそれ周辺を何とかしないと...

今のところインターフェースで良さそうなのでinterface として Enemyを定義。

Java

1interface Enemy{ 2 int attack(); 3}

で、これを継承(厳密には実装だけど。)してスライムやらのクラスを定義。

Java

1public class Slim implements Enemy{ 2 public Slim( int id ){ id_ = id; } 3 public int attack(){ return ap_; } 4 private int ap_; // attack point. (攻撃力) 5 private int id_; // このオブジェクトの番号? 6}

こうすれば、

Java

1Slim slim1 = new Slim(1); 2int a = slim1.attack(); 3// a のダメージを受けた!

みたいにできる。

でもこれはあまりよくない。

オブジェクト指向設計 getter, setterを使うなとはどういうことかを読むと、「データはオブジェクトに任せるべき」らしいです。

よって仕様そのものを変更します。

Enemyインターフェースよりも Chara抽象( インターフェースでもいいけど ) にしたほうがいいかな。

参考: アブストラクト

Java

1public abstract class Chara{ 2 abstract boolean attack( Chara c ); 3 abstract boolean attacked( int n ); // 攻撃されたときの処理 4}

これを継承してSlimやらを定義。

Java

1public class Slim implements Enemy{ 2 public Slim( int id ){ id_ = id; } 3 public boolean attack( Chara c ){ 4 if( c.attacked( ap_ ) ){ // 攻撃して相手が HP = 0 なら 5 return true; 6 } 7 return false; 8 } 9 public boolean attacked( int n ){ 10 hp_ -= n; // hp_ = hp_ - n; と同義 11 if( hp_ >= 0 ) return true; 12 return false; 13 } 14 private int ap_; // attack point. (攻撃力) 15 private int id_; // このオブジェクトの番号? 16 private int hp_; // HP 17}

のようにHPやらMPやらはオブジェクトが管理するようにする。

で、attackメソッドに攻撃対象のオブジェクトを渡せば攻撃側のap_ ( 攻撃力 ) による攻撃が差し引かれて...っていう風に。

Java

1// mainメソッド等の呼び出し元で 2Slim slim1 = new Slim(1); 3Hero hero = new Hero(1); 4slim1.attack( hero ); // 主人公に攻撃 5hero.attack( slim1 ); // スライム( スライム1 ) に攻撃

みたいにできる。

即席だからものすごい適当で、本来ならattackedは親であるabstractではprotectedでmainメソッドのような外部からは触れないようにしたり、

コンストラクタをprotectedかなんかにしてデザインパターンのFactoryパターンかなんかで

  1. ファイルから前回の攻撃力やらHPやらのデータを取得
  2. そのデータからオブジェクトを生成して返す

みたいな感じでやったりするはずだけど、あくまで例だから省略。(スルー)

ここまでが準備段階。

で、問題の

slime,Dragon,Devilの中からランダムに取り出して、最終的に『勇者は(10,100,300のどれか)のダメージを受けた!』と表示することは可能ですか?

ですけど、これは私なら先ほどのChara抽象の配列かリスト等を生成。

Java

1List<Chara> enemies = new ArrayList<Chara>(); // 敵用arrayリスト

で、オブジェクト指向を取り入れた言語では

子クラスでnewして 親で保持することが可能です。

本来なら ArrayList<Chara> ... = new ArrayList<Chara>(); となっているはずですが、
List<Chara> ... = new ArrayList<Chara>(); としますよね?

それと一緒です。

参考: インターフェース

ということで

Java

1// List<Chara> enemies =...; 2enemies.add( new Slim1(1) ); 3enemies.add( new Slim2(2) ); 4enemies.add( new Dragon(1) ); 5...

と登録しておき、乱数を発行して

Java

1// int r; // すでに乱数は発行されているものとして 2enemies[r].attack( hero );

のようにできる。

もちろん、"スライム1によってダメージ10を受けた..." 的な文章も出せるはずだけど、そこは質問者さんが工夫してね。

投稿2018/10/18 03:14

BeatStar

総合スコア4958

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

porpora_0316

2018/10/18 06:39

細かく教えて下さってありがとうございます。 ベストアンサーは下の方にしたのですが、参考にさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問