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

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

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

RPG (Report Program Generator)とは、IBMの System i(AS/400)サーバ向けのプログラミング言語です。

Java

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

Q&A

解決済

2回答

18540閲覧

abstract クラスがフィールドを持つのは正しいか

chankane

総合スコア139

RPG

RPG (Report Program Generator)とは、IBMの System i(AS/400)サーバ向けのプログラミング言語です。

Java

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

1グッド

0クリップ

投稿2017/08/11 13:19

編集2017/08/11 23:47

###前提・実現したいこと
こんばんは、毎度お世話になっております。自分のコードをリファクタリング中に疑問に思ったことがあったので質問させてください。
題名の通り、abstract クラスがフィールド(public static final でない)を持つのは正しいかが疑問です。
abstractに関してまだ、こうやって使うんだみたいな感覚がわかってないので、なにとぞご教授よろしくお願いいたします。

###自分が疑問に思っている部分のコード
キャラクターを管理する抽象クラスAbstractCharacter

java

1// import 省略 2abstract public class AbstractCharacter 3{ 4 private int hp; // このようにabstract クラスがフィールドを持ってよいか、疑問に思いました。 5 private int mp; 6 private Image image; 7 8 private Image readImage(URL url){ 9 // 画像読み込み省略 10 return 画像 11 } 12 13 protected void addHp(int hp){ 14 this.hp += hp; 15 } 16 17 protected void addMp(int mp){ 18 this.mp += mp; 19 } 20 21 public AbstractCharacter(int hp, int mp, URL url){ 22 this.hp = hp; 23 this.mp = mp; 24 this.image = this.readImage(url); 25 } 26 27 abstract public void attack(); 28 29// その他の処理は省略 30}

AbstractCharacterを継承したWizardクラス

java

1// import 省略 2public class Wizard extends AbstractCharacter 3{ 4 public Wizard(){ 5 super(1500, 5000, Wizard.class.getResource("Wizard.png")); 6 } 7 8 @Override 9 public void attack(){ 10.addHp(-200); 11 super.addMp(-50); 12 } 13// その他の処理は省略 14}

###フィールドを持たせないように上のコードを直したら

キャラクターを管理する抽象クラスAbstractCharacter

java

1// import 省略 2abstract public class AbstractCharacter 3{ 4 // private int hp; // フィールドもない 5 // private int mp; 6 // private Image image; 7 8 // コンストラクタはない 9 // public AbstractCharacter(int hp, int mp, URL url){} 10 11 abstract public void attack(); 12 13// その他の処理(abstract なメソッド)は省略 14}

AbstractCharacterを継承したWizardクラス

java

1// import 省略 2public class Wizard extends AbstractCharacter 3{ 4 private int hp; // 代わりに派生クラス側でフィールドを全て記述 5 private int mp; 6 private Image image; 7 8 private Image readImage(URL url){ 9 // 画像読み込み省略 10 return 画像 11 } 12 13 public Wizard(int hp, int mp, URL url){ 14 this.hp = hp; 15 this.mp = mp; 16 this.image = this.readImage(url); 17 } 18 19 @Override 20 public void attack(){ 21.hp -= 200; 22 this.hp -= 50; 23 } 24// その他の処理は省略 25}

###なぜ疑問に思ったか

  1. こういった記述のコードを見たことがないから
  2. php を教わった先生に、「抽象クラスに実装があってもあまりうれしくない」と言っていたことを思い出したから
KiyoshiMotoki👍を押しています

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

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

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

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

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

Stripe

2017/08/11 14:20

とりあえず、abstractクラスになっていませんが?
chankane

2017/08/11 14:22

すみませんミスです。修正します
Stripe

2017/08/11 14:36

abstractと書いただけでは、abstractクラスとしての意味がないですよ。
chankane

2017/08/11 14:42

それはコメント文に書いた通り省略しています。省略しないほうがよろしかったですか?お返事次第で追加いたします。よろしくお願いしますm(._.)m
Stripe

2017/08/11 15:37

あなたが提示したコードは、ただ単にクラス継承を表すものでしかありません。これは今回の質問とどんな関係があるんですか?あなたが何を疑問に思っているのか、このコードからは読み取れません。
chankane

2017/08/11 23:52

abstractなメソッドとコメント文と直した場合こうなるという例を追加致しました。まだ要望があるようでしたら、情報修正致します_(._.)_
guest

回答2

0

別に非抽象メソッドをもっていても問題ないと思います。抽象クラスの性質の一つ「派生クラスの共通の親」として運用するうえで、共通メソッドやフィールドを書いておくというのはありえるはずです。ただ、抽象メソッドを一つでも持つのであればそれは抽象クラスでなければなりません。

抽象クラスの最たる性質は「直接インスタンス化できない」ことです。派生クラスに、抽象メソッドを具象化することを要求します。そして、派生先が抽象メソッドの存在しない具象クラスとなれば、これに対してインスタンス化が可能となります。

要するに、「派生前提の中間的な共通部品」とかの意味合いがあります。

もちろん、すべてのフィールドをなくしてメソッドをabstructにしても問題はありません。ただし、それをするならばInterfaceで充分です。しかもjavaの場合は、Intefaceは多重実装可能(classの多重継承は不可能)なので、Intefaceの方が適切です。

投稿2017/08/11 16:37

HogeAnimalLover

総合スコア4830

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

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

chankane

2017/08/12 00:31

おはようございます。「派生前提の中間的な共通部品」とかの意味合いですか。 とてもわかりやすいです。つまり、abstract クラスがフィールドを持つのはありということですね。 そちらの方が便利なので、今後共通する部分はどんどん基底クラスに書いていこうとおもいます。ご回答ありがとうございました。
guest

0

ベストアンサー

こういった記述のコードを見たことがないから

普通にありますよ。

「TemplateMethodパターン」で検索してみてください。

抽象クラスにメインの実装があります。切り替えたい箇所を抽象メソッドで記述します。
共通で使うメンバ変数があれば抽象クラスに実装します。

「抽象クラスに実装があってもあまりうれしくない」

そういう場合はInterfaceを使えばいいのかなと思います。
Interfaceを使えば実装は持ちません。

投稿2017/08/11 15:26

Tak1016

総合スコア1408

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

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

chankane

2017/08/12 00:52

template method パターンですか。初知りです。ググってみましたが普通に使われているみたいですね。「こういった記述のコードを見たことがないから」なんていって勉強不足だなと思いました。 今回の例では、Wizardの他にも、Knight、Soldier、Archer... とドンドン増えそうなのでその template method パターンとしておくととても管理が楽になりいいと思います。なんかこうゆうのって無意識で使ってしまっていることもけっこうありますね。 ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問