回答編集履歴

3

追記2

2021/12/18 15:13

投稿

BeatStar
BeatStar

スコア4958

test CHANGED
@@ -159,3 +159,65 @@
159
159
 
160
160
 
161
161
  OOPは単に考え方なので、別にOOP的に考える必要はありませんが、今回はどうやらOOPについて学びたいらしいので。
162
+
163
+
164
+
165
+ [追記2]
166
+
167
+
168
+
169
+ > クラスの継承では、スーパークラスにない機能をサブクラスで…
170
+
171
+
172
+
173
+ 継承や実装はメソッドを追加したり等の拡張のためではなく、
174
+
175
+ **同一視するため**です。
176
+
177
+
178
+
179
+ 少なくとも現代においては拡張するために継承するぐらいなら『コンポジションでやれ』と言われます。
180
+
181
+ 簡単に言えばオブジェクトが別のオブジェクトを持つ感じです。
182
+
183
+
184
+
185
+ OOPにおいては、『**オブジェクトだけが対象データと処理方法を知っている**』という状態にするのが基本です。
186
+
187
+
188
+
189
+ なので別に継承とかは必要ないのです。
190
+
191
+
192
+
193
+ Javaでいえば ArrayListとLinkedListはListを実装しています。
194
+
195
+ これらを使う場合、『データを保持しておくこと』と『データを取り出すこと』とかだけが重要で、内部処理は意識しませんよね。
196
+
197
+ もちろん、生成するときは考えるとは思いますが。
198
+
199
+
200
+
201
+ そこで、Listというインターフェースを設けてこれを実装してArrayListとかを定義していれば、
202
+
203
+ 呼び出し側はデータ構造を意識せずに命令するだけでよくなります。
204
+
205
+
206
+
207
+ でも、呼び出し側からすると、デザインパターンでいうFactoryパターンのように親の方で返されると、
208
+
209
+ 子クラスのメソッドは見えません。
210
+
211
+ よって子クラスで追加されたメソッドは使えないのです。
212
+
213
+
214
+
215
+
216
+
217
+ 一応、キャストすれば使えますが、理解していないと危険なので。
218
+
219
+
220
+
221
+ 保持している型でしか認識できません。
222
+
223
+ ただし、実際の処理は子クラスで定義されたものです。

2

追記1.1

2021/12/18 15:13

投稿

BeatStar
BeatStar

スコア4958

test CHANGED
@@ -155,3 +155,7 @@
155
155
 
156
156
 
157
157
  誰が使うかとかではなく、そのクラスとかを抽象的に言ったものが親クラスです。(インターフェースだったりもするが)
158
+
159
+
160
+
161
+ OOPは単に考え方なので、別にOOP的に考える必要はありませんが、今回はどうやらOOPについて学びたいらしいので。

1

追記1

2021/12/18 13:40

投稿

BeatStar
BeatStar

スコア4958

test CHANGED
@@ -93,3 +93,65 @@
93
93
  それに、何がしたいのでしょうか?
94
94
 
95
95
  Planeクラスのplayメソッドとかを見ると、「引数をまったく利用していない」です。それならいっそ引数無しの方がいいです。(多分、今回の問題を解決してからやろうとしているのかもしれませんが、そうじゃないかもしれないし)
96
+
97
+
98
+
99
+ -----
100
+
101
+
102
+
103
+ [追記1]
104
+
105
+
106
+
107
+ > ということは、Viecleクラスにspeedの値を返すコードが必要だということでよろしいでしょうか?
108
+
109
+
110
+
111
+ Yes。まあ、Viecleをabstractかinterfaceとして子クラス(Planeクラスとか。孫だけど)で実装してもいいですし、Player側にplayメソッドみたいに「実装クラス側で実装せよ」的にしてもいいですが。
112
+
113
+ 少なくとも、保持しているときの型にあるメソッド等しか使えないので、Player側で見える状態にすべきです。
114
+
115
+
116
+
117
+ それと、Player抽象クラスの意図がよくわかりません。継承や実装を使ってポリモーフィズムを表現するのであれば、「抽象度」をキーにすべきです。
118
+
119
+
120
+
121
+ よく例として出される、「猫がニャーと鳴いて犬がワンと鳴く」系で、
122
+
123
+
124
+
125
+ ```Java
126
+
127
+ Animal animal1 = new Dog("ポチ");
128
+
129
+ Animal animal2 = new Cat("タマ");
130
+
131
+ animal1.bark();
132
+
133
+ animali2.bark();
134
+
135
+ ```
136
+
137
+
138
+
139
+ のような場合、関係のないAnmimalがあるのではなく、犬と猫は抽象的に言えば『動物』ですからAnimalとして保持します。そして「その動物だけが本能的に鳴き方を知っている」ので「鳴け」と命令すれば各々の泣き方(猫ならニャー、犬ならワンとか)で鳴くという感じです。
140
+
141
+
142
+
143
+ 質問者さんの今のコードだと、
144
+
145
+
146
+
147
+ Animalインターフェースを実装してPlayer抽象クラスを定義し、Player抽象クラスを継承してDogクラスを定義する……みたいな状態です。
148
+
149
+
150
+
151
+ 確かにユーザであるプレイヤーが操作しますが、抽象的に言ったら正しいでしょうか?
152
+
153
+ つまり、犬・猫を抽象的に言えばプレイヤーで、プレイヤーを抽象的に言えば動物(Animal)である。ということです。正しいでしょうか?
154
+
155
+
156
+
157
+ 誰が使うかとかではなく、そのクラスとかを抽象的に言ったものが親クラスです。(インターフェースだったりもするが)