アプリ版:「スタンプのみでお礼する」機能のリリースについて

初めまして、お世話になります。JAVAの入門者です。継承のところまで進みましたが、代入と配列のクラス化で困っています。
環境は、Windows7 professional、JDK1.6.0_33、エディターはnotepad++ないしEclipse4.2です。プログラムは以下のとおりです:

class PersonalData{ //継承元クラス
String name;
String phoneNumber;
public String getContact(){
return name + "の連絡は" + phoneNumber + "に電話です";
}
}

class MailPersonalData extends PersonalData{ //派生クラス
String mailAddress;  //問題となっているフィールド
public String getContact(){ //オーバーライド
return name + "の連絡は" + mailAddress + "にメールです";
}
}

public class Main{ //実行クラス
public static void main(String[] args){
PersonalData[] pdArray = new PersonalData[100];

MailPersonalData mpd = new MailPersonalData();
PersonalData pd = new PersonalData();

pdArray[0] = mpd; //代入
pdArray[1] = pd;

pdArray[0].name = "ジョン";
pdArray[0].mailAddress = "xx@xxxx"; //ここでエラー発生
pdArray[1].name = "ポール";
pdArray[1].phoneNumber = "012-345-6789";

System.out.println(pdArray[0].getContact());
System.out.println(pdArray[1].getContact());
}
}

というプログラムを作りましたが、コマンドプロンプトによるコンパイル時に
Main.java27:シンボルが見つけられません
シンボル:変数 mailAddress
場所:PersonalDataのクラス
pdArray[0].mailAddress="xx@xxxx"
^   (^は.の直下にあります)
とエラーが出てしまいます。Eclipse4.2では「解決できないか、フィールドではありません」と表示されます。
プログラム23行目のpdArray[0] = mpd; の代入によりpdArray[0]を派生クラス型にしましたが、派生クラス内のフィールドmailAddressがmainでは認識されていないようです。継承元クラスに記述されているphoneNumberはフィールドとして認識されています。
配列ではなくpd0、pd1といった個別のクラス型変数を作成した場合はmailAddressもフィールドとして認識され期待している結果が得られました。期待している結果は次のとおりです:
ジョンの連絡はxx@xxxxにメールです
ポールの連絡は012-345-6789に電話です

教えて!gooに似た質問がありましが、少し違うようです。(http://oshiete.goo.ne.jp/qa/1201607.html)
その他、googleでキーワードに配列のクラス化、継承、オーバーライドなどを用いて検索しましたが解決法は得られませんでした。
なにぶん初心者の為、非常に的外れなことをやっていると思い誠に恐縮ですが、どうかご容赦ください。御教授のほど何卒宜しくお願い申し上げます。

A 回答 (2件)

配列を宣言したとき、その要素へのアクセスは宣言された型(この場合はPersonalData型)を使用することになります。

したがって、PersonalDataにないフィールドやメソッドにアクセスすることはできません。

アクセス時の対処法は、……あることはありますが初心者は使わないほうがいい手法なので教えません。
# それに頼ることを覚えるとその便利さゆえにオブジェクト指向を身につけられなくなる悪魔の手法ですので

それよりも、

MailPersonalData mpd = new MailPersonalData();
mpd.name = "ジョン";
mpd.mailAddress = "xx@xxxx";
pdArray[0] = mpd;

PersonalData pd = new PersonalData();
pd.name = "ポール";
pd.phoneNumber = "012-345-6789";
pdArray[1] = pd;

というふうに配列への代入の前に値を設定しておきましょう。
    • good
    • 0
この回答へのお礼

迅速でかつ分かりやすい回答をありがとうございます!(涙
現在使用しているテキストを見返してみると、「コンパイラは変数の型しか見ず、実際に変数に入っているインスタンスの型が何であるかはチェックしない」と記述されていました。その意味が初めて分かりました。これでまた前進できます。
しかし、ちょっとした疑問が生じてしまいました...。mpdもpdも代入できる配列pdArrayは、継承元クラスであるPersonalData型で宣言するしかないのでしょうか?それとも、もっと別なスマートな配列宣言の方法があるのでしょうか?
重ね重ね初歩的な疑問で恐縮です。もし宜しければ御教授下さい。

お礼日時:2012/08/14 01:11

PersonalData ってクラスに mailAddress ってメンバー, あるの?

    • good
    • 0
この回答へのお礼

早速のご回答、ありがとうございます。PersonalDataクラスにはmailAddressというメンバーはありませんでした。クラスの宣言と継承の理解が不十分でした。今回の件で勉強になり、誠にありがとうございました。

お礼日時:2012/08/14 19:11

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!