スーパークラスからサブクラスのメソッドを使おうとする、以下のプログラムでつまずいています。
Aを継承したB、Cクラスのインスタンスを作成し、スーパークラスであるA型の配列asにまとめます。
それからループでas[i]にはいっている各インスタンスのメソッドを使いたいのですが、
スーパークラスAにmethod()がないためコンパイルできません、Aにmethod()を作るとA.method()が実行されます。
BとCを同じ配列に保存し、かつそれぞれのmethod()を実行したい場合どのようにしたら良いのでしょうか。
ご教授ください、どうぞよろしくお願いします。
class Main{
private B b;
private C c;
private A[] as = new A[2];
void mainMethod(){
as[0] = b = new B();
as[1] = c = new C();
for(int i=0; i<3; i++){
as[i].method();
}
}
}
class A{}
class B extends A{
void method(){
System.out.print("It is B");
}
}
class C extends A{
void method(){
System.out.print("It is C");
}
}
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
>スーパークラスAにmethod()がないためコンパイルできません、Aにmethod()を作るとA.method()が実行されます。
まずここですが、これはありえません。
Javaではコンパイル時には変数の型で判断するのでAにmethod()メソッドがなければコンパイルエラーになりますが、実行時、つまりJVMは実際のオブジェクトを判断して実行します。
このため、もしAにmethodが定義されていたらコンパイルエラーにはならず、かつ実行時にはそれぞれのオブジェクトのmethod()メソッドを呼び出します。
また今回のようにAにmethod()を書きたくないのであれば普通は instanceof というものを使います。これは変数が参照している実際のオブジェクトがどのクラスのオブジェクトなのかを調べるのに使います。
以下にサンプルを示します。この方法ならAにmethodがなくても上手くいきます。
public class Main{
private B b;
private C c;
private A[] as = new A[2];
public Main(){
as[0] = b = new B();
as[1] = c = new C();
for(int i=0; i<as.length; i++){
if(as[i] instanceof B) {
((B)(as[i])).method();
}
}
}
public static void main(String[] args){
new Main();
}
}
class A{public void method(){System.out.println("A");}}
class B extends A{
public void method(){
System.out.print("It is B");
}
}
class C extends A{
public void method(){
System.out.print("It is C");
}
}
No.3
- 回答日時:
追加、修正はコメントした3箇所。
mainMethod内のfor文のバグの存在も含め、本当にAクラスにmethodメソッドを作って実行してみたのか疑問がある。
質問のプログラムではインスタンスメソッドであったが、methodメソッドをクラスメソッドにしていたなら静的に定まっているasの型にしたがってAクラスのmethodメソッドが呼ばれる。
もし具体的なメソッドをAクラスで実装する必要がなかったりすべきでないのならmethodメソッドを抽象メソッドに(もちろんAクラスは抽象クラスに)するか、methodメソッドがpublicになってもいいのならAクラスをインタフェイスとして定義することも考えてもいいかもしれない。
class Main {
private B b;
private C c;
private A[] as = new A[2];
void mainMethod() {
as[0] = b = new B();
as[1] = c = new C();
for(int i = 0; i < as.length; i++) { // as[2]は存在しない
as[i].method();
}
}
public static void main(String[] args) { // java Mainで実行できるように付加
new Main().mainMethod();
}
}
class A {
void method() { // 質問者が作成してみたところ呼ばれたというメソッド
System.out.print("It is A");
}
}
class B extends A {
void method() {
System.out.print("It is B");
}
}
class C extends A {
void method() {
System.out.print("It is C");
}
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP アコーディオンPHPが上手くいかない 3 2022/07/15 16:29
- Java インスタンス ダウンキャストについて以下の解釈であっているか教えて欲しいです。 サブクラスをスーパー 1 2022/03/27 18:53
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- その他(プログラミング・Web制作) どうしてもエラーが解決できません。 1 2022/07/23 04:32
- 英語 figureの意味 3 2023/06/12 05:01
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- Ruby No route matches [GET] "/posts/5/destroy" 1 2022/03/24 13:00
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- その他(プログラミング・Web制作) pythonのプログラムについての質問です。 1 2023/05/26 10:31
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Java初級 引数に適用できません
-
C言語での文字列より値を抜き出す
-
レコード件数の表示
-
C# 点の描き方をおしえてくだ...
-
String.containsの反対機能はあ...
-
StringBufferからStringへキャ...
-
abstract と static を一緒に付...
-
YYYYMMDD書式の日付に対する適...
-
getBunds()の使い方
-
メソッドの引数に指定されてい...
-
Strutsでチェックボックスの値...
-
コマンドライン引数のチェック
-
System.out.print
-
C# asp.net HTMLタグのエスケ...
-
privateのメソッドをリフレクシ...
-
VB.Net: クラスの共有メソッド...
-
java ジェネリックスに関して
-
スーパークラスからサブクラス...
-
getBinaryOutputStream()が使え...
-
C# 他のnamespaceにあるメソッ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
レコード件数の表示
-
Java初級 引数に適用できません
-
String.containsの反対機能はあ...
-
abstract と static を一緒に付...
-
下記のリストならno002が含まれ...
-
Google Apps Script で getRang...
-
メソッド宣言の戻り値の型にク...
-
Strutsでチェックボックスの値...
-
StringBufferからStringへキャ...
-
readLine()ではじめから読み直...
-
javaに"search"という関数 or ...
-
なぜprotected overrideなのか
-
C# 点の描き方をおしえてくだ...
-
public static void main (Stri...
-
メソッドの引数に指定されてい...
-
別クラスのmainメソッドの実行
-
YYYYMMDD書式の日付に対する適...
-
C# の ByVal と ByRef について
-
Javaの関数名が長い?
-
Java初心者です、エラーの意味...
おすすめ情報