voidの性質や使い方、showメソッドについて

このQ&Aのポイント
  • voidの性質や使い方、showメソッドについての質問
  • 1ファイルに2クラスがあるプログラムでのvoidの性質や使い方についての質問
  • CatクラスとStartクラスのshowメソッドの引数の有無の違いによるエラーについての質問
回答を見る
  • ベストアンサー

voidの性質や使い方、showメソッドについて

1ファイル1クラスの原則に反しますが、敢えて1ファイルに2クラスあるプログラムにおいて、voidの性質や使い方、showメソッド等について教えてほしいです。 ファイル名はStart.javaです。 --------------------------------- package sample; class Cat { String name; int age; void show(String name,int age) { System.out.println("名前は" + name + "です"); System.out.println("年齢は" + age + "歳です"); } } public class Start { public static void main(String[] args) { Cat cat1 = new Cat(); cat1.name = "太郎"; cat1.age = 28; cat1.show(); } } --------------------------------- 「cat1.show();」のところでエラーが出ていますが、Eclipseでそのまま実行してみますと。 ~~~~~~~~~~~~~~~~~~~ Exception in thread "main" java.lang.Error: Unresolved compilation problem: 型 Cat のメソッド show(String, int) は引数 () に適用できません at sample.Start.main(Start.java:16) ~~~~~~~~~~~~~~~~~~~ といったエラーが出てきます。しかし、Catクラスの「void show(String name,int age) 」の箇所を「void show() 」のように、Startクラスと同じく引数の中身を空にしますと。 |||||||| 名前は太郎です 年齢は28歳です |||||||| と、正しい結果が出力されたのです。 最初のプログラムは、Catクラスのshowメソッドには引数があり、Startメソッドのshowメソッドには引数が無い状態でした。 修正したプログラムでは、どちらのクラスのshowメソッドにも引数はありませんでした。 最初のプログラムでも、mainメソッドを実行して、nameとageに値を格納して、showメソッドでCatクラスの方で定義したshowメソッドを呼び出すといった流れで、正しい値は出るはずだと自分は考えたのですが。 なぜエラーになってしまったのか、どうして2つのクラスのshowメソッドの引数が空だとうまく結果が出力されたかにつきまして、お教えいただけないでしょうか。 よろしくお願い致します。 ※OKWAVEより補足:「Webシステム開発」についての質問です。

  • Java
  • 回答数5
  • ありがとう数6

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

1歩ひいて考えたとして・・・ ローカル変数をクラス変数に移動するだけの関数。 void set_name(String name) { this.name=name; //なぜこんなことをするか?というと //名前として適切か?をテストしてOKなら代入などの禁則処理ができるため //いまは、テストでnameですが、例えば名前は漢字か?読みはカタカナか?などをテストできるようにしたいので。 } void set_age(int age) { this.age=age; //なぜこんなことをするか?というと //年齢として適切か?をテストしてOKなら代入などの禁則処理ができるため //年齢なのにマイナスだったり、事実上あり得ない1000歳だとかをチェックできます。 } void show() { System.out.println("変数の名前は" + this.name + "です"); System.out.println("変数の年齢は" + this.age + "歳です"); } だったら、OKですよ。 set_xxx系の返り値をBOOLにして、正しく反映できたか?を返し if (hogehoge.set_xxx(para)!=true) { /* 設定が不適切だった時の処理 */ } って書いていけば、あとで、受け付ける文字が変わったり範囲があるものを作ったりしても、 根元で1発で処理できるので、便利ってな。(今回のはサンプルなので、あんまり意味ないけど) cat1.age = 28; これだと、どんな値でも入ってしまうのと、代入自体は適切なので、 エラーも出ませんし。値が理想とするものか?をだれもテストできない。 当然変な所でバグがでて、ハマる!ってな。 まだ、"private"や"public"などの属性がないので、 全部"public"ですが、 クラス内の変数と、クラス内の関数のどちらも、 外からアクセスできる/できないについて設定できますよ。 とりあえず、今回の件は、デバッガーがあるなら、 PRINT系命令で一度ブレイクポイントを付けて、 各変数がどこをさしているのか?を見ると、 すぐわかると思いますので。ファイトっす

nihonbashiboy
質問者

お礼

ありがとうございます。 はい、 void set_name(String name) { this.name=name; } void set_age(int age) { this.age=age; } のようなコードを読んだことがありまして、なぜこういったことを行うのかが疑問でした。 チェック機能があったんですね(^^; privateやpublicは確かに、意識して書いてないですね…それも意識できるようになれたら、と思います。 if (hogehoge.set_xxx(para)!=true) { /* 設定が不適切だった時の処理 */ } は、自分の実力では活用法がまだ想像できないですね…また質問するかもしれませんので、その際はすみませんがよろしくお願いします<m(__)m> デバックモードでも追ってみます。

その他の回答 (4)

  • ubku
  • ベストアンサー率37% (227/608)
回答No.4

No.2です 重要なところで誤解があるようですので・・。 次郎25歳が出てきたのはフィールドが書き換えられたからではありません。 フィールドは太郎28歳のままです。 フィールドとメソッドの仮引数に同じ変数名を付けることはできますが、別物なのです。メソッド内で 「 age 」とだけ書くと仮引数の事になります。 もう一つ、この会話で「インスタンス」という語が出てこなかったので、 「クラス」と「インスタンス」の違いについては理解されていますか?「クラス」は定義「インスタンス」は実体です。 this は 同じクラスではなく、同じインスタンスの自身を指します。 Cat cat1= new Cat(); Cat cat2= new Cat(); Cat cat3= new Cat(); ・ ・ それぞれ別のインスタンスが生成されます、フィールドも別々なので、それぞれ別の値を保持することができます。また、this は それぞれの自身を指します。 これも実際に動かしていろいろやってみてください。 質問内容から離れすぎましたのでこれにて終了です。 失礼いたしました。

nihonbashiboy
質問者

お礼

はい、クラスとインスタンスについては、大丈夫です。 が、thisは同じクラスではなく同じインスタンス自身だったのは認識不足でした、ありがとうございます。 仮引数nameやageは、フィールドとメソッドで異なるのですね。 確かに今回はメソッドで「太郎」「28」と値を入れているので、メソッドの方は実引数ですね。 また復習してみます。

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.3

>Exception in thread "main" java.lang.Error: Unresolved compilation problem: >型 Cat のメソッド show(String, int) は引数 () に適用できません > >at sample.Start.main(Start.java:16) エラーメッセージをきちんと読まれたらわかると思うのですけど。 Catのメソッドshow(String, int)は、1番目にString型の引数が、2番目にint型の引数が必要なのに、 show()と引数なしで呼んでるからエラーになってるんです。 >なぜエラーになってしまったのか、どうして2つのクラスのshowメソッドの引数が空だとうまく結果が出力されたかにつきまして、お教えいただけないでしょうか。 CatクラスのshowメソッドのString型の第1引数とint型の第2引数が必要という仕様と、使い方が異なってたからです。 それをCatクラスのshowメソッドを引数なしという仕様に変える事で使い方の方に合わせたことで解決したという事です。

nihonbashiboy
質問者

お礼

そうなんですね。 Catクラスのshowメソッドは引数ありの仕様なのに、それをStartクラス内で引数無しで利用しようとしたのが原因なんですね。 何となく頭がスッキリしました、ありがとうございます!

  • ubku
  • ベストアンサー率37% (227/608)
回答No.2

void show(String name,int age) { ~ } と引数が2つ定義されているのに cat1.show(); では引数がありませんね。コンパイラはカンカンになって怒ります。 void show() { ~ } を定義すれば許してもらえます。 void の性質については、返り値を持たない、ですが、本件のエラーには関係ありません。 回答はここまでですが、むしろ最初のプログラムで、やってみてほしいのですが、 class Cat { String name; int age; void show(String name,int age) { System.out.println("名前は" + this.name + "です"); System.out.println("年齢は" + this.age + "歳です"); System.out.println("名前は" + name + "です"); System.out.println("年齢は" + age + "歳です"); } } ここで、 cat1.name = "太郎"; cat1.age = 28; cat1.show(”次郎”,25); を実行するとどうなるでしょうか?

nihonbashiboy
質問者

お礼

ありがとうございます、ubkuさんのコード、試してみました。 thisは確か、同じクラス内に限り値を呼び出せる…的な使い方だったと思います。 だからStartクラスの「cat1.name = "太郎";」「cat1.age = 28;」で、Catクラスのフィールドを参照して値を代入し。 Catクラスの変数nameが"太郎"、変数ageが28という値になりまして。 同時に「this.」が付いていたので、たとえStartクラスのshowメソッド内で引数に「”次郎”,25」が指定され、変数nameとageの値が変わったとしても。 ――――――― 名前は太郎です 年齢は28歳です ――――――― と、Catクラスの中でのnameとageの値が、出てきました。 ――――――― 名前は次郎です 年齢は25歳です ――――――― が出てきたのは、Catクラスのshowメソッドを呼び出した後に、引数を指定してnameとageの値を変えたから、Catクラス内の値は出てこなかった…。 こういった認識で正しいでしょうか? もし誤りがありましたら、お手数ですが再度ご指摘いただけますと幸いです<m(__)m>

回答No.1

あら。 最初のケースは cat1.name = "太郎"; cat1.age = 28; cat1.show(); ではなく cat1.show("太郎",28); で、コンパイルが通ります。 理由は、これ void show(String name,int age) { 2個のパラメーターを必要とする宣言があったためで、 cat1.show(); と、省略したことで、必要なものがない!というエラー 逆に、 void show() の時に、エラーが出なかった理由は、 cat1.name = "太郎"; cat1.age = 28; の代入が優先されたため。 ローカルスコープとクラス内のスコープの違いです。 void show(String name,int age) { System.out.println("名前は" + name + "です"); この時の"name"は、cat1.nameではなく、 void show(String name,int age) {←ここの"name"を参照している。 省略した場合は、関数の外である、 class Cat { String name; ←ここ を見ていたので、表示がされたという具合ですね。 もし、 void show(String name,int age) { System.out.println("名前は" + this.name + "です"); System.out.println("年齢は" + this.age + "歳です"); と書いていた場合は、パラメーターとして、name,ageに 何が与えられても、this(つまりCATそのもの)の変数を見ます。 なので、これを省略したため、コンパイラが自動判断した結果による 違いですね。 void show(String name,int age) { System.out.println("変数の名前は" + this.name + "です"); System.out.println("変数の年齢は" + this.age + "歳です"); System.out.println("パラメタの名前は" + name + "です"); System.out.println("パラメタの年齢は" + age + "歳です"); } と書いて、呼び出し元を Cat cat1 = new Cat(); cat1.name = "太郎"; cat1.age = 28; cat1.show("花子",14); とでもすれば、理解できるかと思います。

nihonbashiboy
質問者

お礼

ありがとうございます、変数nameがどのように処理されているか、よくわかりました! this.を使えば引数に何の値が入ろうとも、フィールドで定義したnameやageを参照してくれるんですね。 「(一方のクラスで)2個のパラーメーターが必要な宣言をしていたのに、(別のクラスで)省略してしまって『必要なものがない!』というエラー」も、覚えておきます。

関連するQ&A

  • コンストラクタとその類似の形について 初心者です。

    コンストラクタについて勉強したばかりのところ、似たような記述に出会い違いが全くわかりません。 プログラム1 class Book { int price; int num = 0; String title; Book(String t, int p) { ...☆ title = t; price = p; } ・      ・       ・ プログラム2 class Cat { String name; String place; int age; void setData(String n, String p, int a) {...★ name = n; place = p; age = a; }      ・      ・      ・ ☆と★の違いがわかりません。どちらも値(変数)を代入してるという点では同じですよね。なぜ★はvoidがつくのに☆はつかないのでしょうか? 本によると☆のほうはコンストラクタで、★はコンストラクタではなくメソッドらしいのですが・・・。使い分けはどういうときするのでしょうか?  よろしくお願いします。

    • ベストアンサー
    • Java
  • クラスを使用した問題

    問題 Mainクラス 1.実行時に引数を付けて実行する。 2.判定クラスのオブジェクトを生成する。 3.args(実行時の引数)から値を取得する。 4.argsから取得した値を引数として、判定クラスのnameメソッドを実行する。 5.argsから取得した値を引数として、判定クラスのageメソッドを実行する。 6.argsから取得した値を引数として、判定クラスのbirthメソッドを実行する。 判定クラス nameメソッド(引数=String) 1.String型の引数を一つ受け取る 2.受け取った引数の値が「name」だった場合、名前を表示する。 戻り値なし。 ageメソッド(引数=String) 1.String型の引数を一つ受け取る 2.受け取った引数の値が「age」だった場合、名前を表示する。 戻り値なし。 birthdayメソッド(引数=String) 1.String型の引数を一つ受け取る 2.受け取った引数の値が「birthday」だった場合、名前を表示する。 戻り値なし。 実行結果 java NameAgeBirth name 岩田 java NameAgeBirth age 27歳 java NameAgeBirth birthday 5月16日 参考例が欲しいです。良かったら参考例をください。よろしくお願いします。

  • コンポジション コンストラクタに引数がある場合

    class Person{ public String name_; public int age_; public Person(String n,int a){ name_ = n; age_ = a; } } class Student{ public Person person_; public int grade_; public Student(Person p,int g){ person_ = new Person("MOTO",2); grade_ = g; } } public class Samconp2{ public static void main(String[] args){ Student asaya_ = new Student(p,0); } System.out.println(asaya_.person_.name+asaya_.person_.age_+asaya_.grade__); } 3のプログラムを見るようにコンストラクタに引数使い、又継承を使わないでPerson クラスのname_ age_ それを拡張したStudetクラスのgrade_をmain関数で表したいのですが(希望としてはname_ "Moto" age_ 2 grade_ 0) 結果としては、System.out.println(asaya_.personn_.name_ + asaya_.person_.age_ +asaya_grade_);で<identifierがありません>となります。 まだ初心者で良く分りません。解決方法をお願いします。

    • ベストアンサー
    • Java
  • コンポジションについて

    public class Person{ public String name_ ; public int age_ ; public Person(){ name_ = "Asaya"; age_ = 61; } } public class Student{ public Person person_; public int grade_; public Student(){ person_.name_ = "Moto"; person_.age_ =2; grade_ = 0; } } public class SamConp1{ public static void main(String[] args){ Person person_ = new Person(); Student asaya_ = new Student(); System.out.println(asaya_.person_.name + asaya_.person_.age_+asaya_.grade__); } } 3つのプログラムを見るようにコンストラクタに引数を使わず、又継承を使わないでPerson クラスのname_ age_ それを拡張したStudetクラスのgrade_をmain関数で表したいのですが(希望としてはname_ "Moto" age_ 2 grade_ 0) 結果としては、 exception in thread "main" java.lang.nullpointerexception at student.<int>(Student.java:6) at SamConp1.main(SampConp1.java:4) となります。 まだ初心者で良く分りません。解決方法をお願いします。

    • ベストアンサー
    • Java
  • 例外処理(throws Exception)について

    Javaでインスタンスを作るときの例外処理を学んでいます。 ageクラス(属性は、private int ageのみ)のt1オブジェクトを作るときに、年齢が0歳以上100歳以下ならt1が作られ、それ以外の場合はエラーを返すようにしたいと思いますが、うまくいきません。 そのため、仮に50歳でオブジェクトを作ってから、年齢を150にした場合を考えましたが、Sample クラスのt1.setAge(150);のところで、「処理されない例外の形」というエラーが返っております。 改善点につきまして、ご教示いただければ幸いです。 ■■ageクラス■■ package ex1; public class age { //***属性***// private int age; //***コンストラクタ***// public age(int data){ this.age= data; } //**メソッド**// public int getAge(){ return age; } public void setAge(int age)throws Exception{ //**年齢が0から100までかどうか**/ if((age > 0) && (age <100)){ this.age = age; } else{ throw new Exception("無効です"); } } } ■■Sample クラス■■ package ex1; public class Sample { public static void main(String[] args) { age t1; t1 = new age(50); t1.setAge(150); System.out.println("t1_age="+ t1.getAge()); } }

  • 計算クラスのメソッドについて

    <問題> Mainクラス mainメソッド 1)実行時に引数を2つ付けて実行する。(数字) 2)計算クラスのオブジェクトを生成。 3)argsの0番目と1番目から値を取得し、int型に変換する。 4)int型に変換した値2つを引数として、計算クラスの足し算メソ   ッドを実行し、戻り値を取得して表示する。 計算クラス 足し算メソッド(引数=int,int) 1)int型の数字を引数として2つ受け取る。 2)二つの引数の値を足し算する。 3)計算した値を戻り値とする。 *********************************************************** 上記の問題についての質問です。 最初mathくらすのメソッドを使うのかと思ったのですが、 足し算を計算するようなメソッドが無かったのでネットで検索 して見つけたcalcAdd()というメソッドを使って記述してみました。 でも「シンボルを見つけられません」のエラーが出てコンパイル 出来ないし、メソッドの使い方も違うような気がするので、 分かる方正しい記述の仕方を教えてください。 package siryou; class Keisan { int cal; int cul; public int tashizan(int a, int u) { cal = a; cul = u; int kekka = (Integer)calcAdd(cal, cul, 0); return kekka; } } class TashiHikiKakeWari { public static void main(String args[]) { Keisan ki = new Keisan(); String str1 = args[0]; String str2 = args[1]; int res1 = Integer.parseInt(str1); int res2 = Integer.parseInt(str2); ki.tashizan(res1, res2); int kekka = ki.tashizan(res1, res2); System.out.println(kekka); } } ************************************************************ calcAdd()メソッドの呼び出し方も間違っている気がするのですが、 そもそもこのメソッドって呼び出せば自動的に計算されるように なっているのですか? それとも足し算を計算する記述は別にしなければならないのでしょうか?

    • ベストアンサー
    • Java
  • クラス名を変えるとコンパイルが通らない

    interface HINA { void write(String str, int age); } class super_class { String name; int age; public void write(String str, int age){ System.out.println(str + "\t" + age); } super_class(String name, int age) { this.name = name; this.age = age; } } class sub_class extends super_class implements HINA { public void write(String str , int age) { System.out.println(str + "\t" + age); } sub_class(String str , int age) { super(str , age); } } public class test3 { public static void main(String[] args) { super_class naru = new super_class("成瀬川なる", 17); super_class shinobu = new sub_class("前原しのぶ", 13); sub_class motoko = new sub_class("青山素子", 15); if (naru instanceof HINA) naru.write(naru.name, naru.age); if (shinobu instanceof HINA) shinobu.write(shinobu.name, shinobu.age); if (motoko instanceof HINA) motoko.write(motoko.name, motoko.age); } } これのsuper_classをOyaに、sub_classをKoにするとコンパイルエラーになります。 何故なんでしょう。 分かる方がいましたら、教えて下さい。 どうぞ宜しくお願い致します。 それと見づらくてどうもすいません。

    • ベストアンサー
    • Java
  • クラスメソッドの仕様

    次のようなクラスメソッドを作りたいのですが、自分で作って見たところ、どのような点を修正すればいいか分かりません。 どうか教えてください。 (1) 次に示す内容を満たすバー(Bar)クラスを作成せよ。 1. バーの右端のx座標(=バーの長さ)、バーの名前を扱う2つのprivateなインスタンス変数を持つ。 2. バーの総数を扱うprivateなクラス変数を持つ。ただし、 ここでいう総数とは、(1)コンストラクタで作成したもの、(2)代入操作で作成したもの、の両方を含む。 3. 引数無しのコンストラクタが呼び出されてバーオブジェクトが作成されると、そのバーのx座標は0以上400未満でランダムに決定され、名前は文字「A」とランダムに決定された0以上10000未満の整数が連接されたものに決定される。 4. バーのx座標を設定するインスタンスメソッドを持つ。 5. バーの名前を設定するインスタンスメソッドを持つ。 6. バーのx座標を取得するインスタンスメソッドを持つ。 7. バーの名前を取得するインスタンスメソッドを持つ。 8. 作成されたバーの総数を取得するクラスメソッドを持つ。 9. 作成されたバーの総数を1増やすクラスメソッドを持つ。 10. 作成されたバーの総数を1減らすクラスメソッドを持つ。 これを自分なりに解釈したところ、 class Bar{ private int x; private String name; private int count; private Bar(){ x=0; count=0; name=""; } public void Bar(){ x = (int)(Math.random()*400); name = "A" + (int)(Math.random()*10000); } public void setBar(int bx){ x=bx; } public void setName(String nm){ name=nm; } public void getX(int bx){ } public void getName(String nm){ } public void getCount(int c){ } } どうか御教授お願いします。

  • エラーメッセージ(初歩)

    こんにちは。早速ですが質問させていただきます。 javaの課題をやっているのですが、どうしてもエラーメッセージ を解決できません。 まずプログラムですが… class Dog1{ private String name; private int age; public Dog1(String n){ name = n; } public Dog1(int a){ age = a; } public void getName(){ System.out.print(name); } public void getAge(){ System.out.print(age); } } class Ex45{ public static void main(String args[]){ Dog1 d = new Dog1(); d.setName("ケイ"); d.setAge(17); System.out.println(d.getName() + "は" + d.getAge() + "才の犬です。"); } } このようなプログラムなのですが、 学校から出された課題なのでいくつか条件があります。 1.main文はそのまま使用する(main文は課題プリントを丸写しの状態です。) 2.Dog1クラスを作成し、Dogクラスの変数はprivate変数とする 以上です。 このような条件でプログラムを考えては見たもののバグが出てしまい 一向に問題が解決しません。 バグの箇所はmain文のd.getName()あたり(void型は使用できない)とのメッセージです。 どなたかよろしくお願いします。

    • ベストアンサー
    • Java
  • メソッドの中に、作ったメソッドを呼び込みたいんですが

    メソッドの中に、作ったメソッドを呼び込みたいんですが シグネチャを int argCheck(String args[]) に指定して、 引数のチェック処理メソッドというものを作成してるんですが、 よくわからないんです。 内容は (1) 引数の数が1個でない場合、1を返却 (2) 引数が『aaa』でも『ZZZ』でもない場合、99を返却 (3) 以外は、0を返却 public class Test { public static void main(String args[]) { Test test = new Test(); int result = test.argCheck(args); test.argCheck(); //メソッドを呼び込み } private int argCheck(String args[]) { if(args[0].length != 1) // 引数の数が1以外の場合 { return 1; // 1を返す } else if (!args[0].equalsIgnoreCase("aaa") && !args[0].equalsIgnoreCase("ZZZ")) //引数が aaa でも ZZZ でもない場合(大/小文字区別せず) { return 99; // 99を返す } else // それ以外の場合 { return 0; // 0を返す } } }

    • ベストアンサー
    • Java

専門家に質問してみよう