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

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

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

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

Q&A

解決済

2回答

10199閲覧

privateのフィールドに外部クラスからアクセスする

退会済みユーザー

退会済みユーザー

総合スコア0

Java

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

0グッド

0クリップ

投稿2018/05/22 15:34

編集2018/05/27 15:47

前提・実現したいこと

こんばんは、Javaについての質問です。
とあるJavaの問題を解いていて、ある程度自力で調べてはみたものの、どうしても分からず困っています。
お助け願います…
下記が問題文となります。

問題文

下記クラスにあるフィールドをprivateにした上で、外部から値を設定したり取得できるように変更しなさい。 ただしhourは0~23,minuteは0~59,secondは0~59の間の値しか設定できないように制限すること。 それ以外の値を設定しようとした場合のエラー文言は任意とする。 使用前提条件のクラス: public class Clock{ int hour; int minute; int second; }

作成途中のソースコード

Java

1// Clockクラス // 2 3public class Clock { 4 private int hour; 5 private int minute; 6 private int second; 7 8 //コンストラクタ 9 Clock(int hour, int minute, int second){ 10 this.hour = hour; 11 this.minute = minute; 12 this.second = second; 13 } 14 15 //SET 16 public void setHour(int hour) { 17 this.hour = hour; 18 } 19 20 public void setMinute(int minute) { 21 this.minute = minute; 22 } 23 24 public void setSecond(int second) { 25 this.second = second; 26 } 27 28 //GET 29 public int getHour(){ 30 return hour; 31 } 32 33 public int getMinute(){ 34 return minute; 35 } 36 37 public int getSecond(){ 38 return second; 39 } 40 41} 42 43 44// Clockクラスを外部から実行するための別クラス、ClockTestクラス // 45 46 47import java.io.*; 48 49public class ClockTest { 50 public static void main(String[] args) throws IOException { 51 52 try{ 53 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 54 55 Clock clock = new Clock(); 56 57 System.out.print("数値を入力してください>" + " "); 58 String str = br.readLine(); 59 60 clock.setHour() = Integer.parseInt(str); 61 clock.setMinute() = Integer.parseInt(str); 62 clock.setSecond() = Integer.parseInt(str); 63 64 // 範囲チェック 65 if ((clock.getHour() > 0) && (clock.getHour() <= 23)) { 66 System.out.println(clock.getHour()); 67 68 } else if ((clock.getMinute() > 0) && (clock.getMinute() <= 59)) { 69 System.out.println(clock.getMinute()); 70 71 } else if ((clock.getSecond() > 0) && (clock.getSecond() <= 59)) { 72 System.out.println(clock.getSecond()); 73 } 74 75 } catch(Exception e) { 76 System.out.print("[ERROR] 数値を再入力してください>" + " "); 77 } 78 79 } 80} 81

制作途中のソースコードの改善(再度修正)

Java

1// Clockクラス // 2 3public class Clock { 4 private int hour; 5 private int minute; 6 private int second; 7 8 //コンストラクタ1 9 public Clock(){ 10 super(); 11 } 12 13 //コンストラクタ2 14 Clock(int hour, int minute, int second){ 15 this.hour = hour; 16 this.minute = minute; 17 this.second = second; 18 } 19 20 //SET 21 public void setHour(int hour) { 22 if(hour > 0 && hour <= 23){ 23 this.hour = hour; 24         /* 25 } else { 26 System.out.println("[ERROR] 数値を再入力してください"); 27 } 28 */ 29 } 30 31 public void setMinute(int minute) { 32 if(minute > 0 && minute <= 59){ 33 this.minute = minute; 34         /* 35 } else { 36 System.out.println("[ERROR] 数値を再入力してください"); 37 } 38 */ 39 } 40 41 public void setSecond(int second) { 42 if(second > 0 && second <= 59){ 43 this.second = second; 44         /* 45 } else { 46 System.out.println("[ERROR] 数値を再入力してください"); 47 } 48 */ 49 } 50 51 //GET 52 public int getHour(){ 53 return hour; 54 } 55 56 public int getMinute(){ 57 return minute; 58 } 59 60 public int getSecond(){ 61 return second; 62 } 63 64} 65 66 67 68// Clockクラスを外部から実行するための別クラス、ClockTestクラス // 69 70 71import java.io.*; 72 73public class ClockTest { 74 public static void main(String[] args) throws IOException { 75 76 77 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 78 Clock clock = new Clock(); 79 80/* 81 System.out.print("数値を入力してください>" + " "); 82 String str = br.readLine(); 83 84 clock.setHour(Integer.parseInt(str)); 85 clock.setMinute(Integer.parseInt(str)); 86 clock.setSecond(Integer.parseInt(str)); 87*/ 88 89//冗長かもしれませんが、入力の仕方を一つずつ入力できるよう修正しました 90 91       System.out.print("hourの数値を入力してください>" + " "); 92 String str = br.readLine(); 93 clock.setHour(Integer.parseInt(str)); 94 95 System.out.print("minuteの数値を入力してください>" + " "); 96 str = br.readLine(); 97 clock.setMinute(Integer.parseInt(str)); 98 99 System.out.print("secondの数値を入力してください>" + " "); 100 str = br.readLine(); 101 clock.setSecond(Integer.parseInt(str)); 102 103 try{ 104 System.out.println("hour" + " " + clock.getHour()); 105 System.out.println("minute" + " " + clock.getMinute()); 106 System.out.println("second" + " " + clock.getSecond()); 107 108 } catch(Exception e) { 109 System.out.println("[ERROR] 数値を再入力してください"); 110 } 111 112 } 113} 114

やりたいこと、困っていること

実行(したい)画面例

hourの数値を入力してください> 100
[ERROR]数値を再入力してください> 23
hour 23
minuteの数値を入力してください> 12
minute 12
secondの数値を入力してください> 36
second 36

現状、このプログラムをコンパイルしようとすると、インスタンス化ができませんというエラーと、clock.setHourに引数がありませんというエラーが出てしまい、実行できません。
実現したいこととしては、キーボードから好きな数値を入力させ、入力値が指定した数値の範囲内であれば出力し次の入力へ、範囲外であればエラー文言を出力、再入力を求めるプログラムを作成したいのですが、setとgetの使い方をうまく理解できていないせいかここから進まず…基礎の話で申し訳ないのですが、ご助言等いただけますと幸いです。
問題文には明記されていませんが、条件としてsetとgetを必ず使用することとなっています。
お手数おかけいたしますが何卒よろしくお願いいたします。

やりたいこと、困っていること(追記)

少し考えてみて、編集し直してみました。エラーは起こらなくなり、setでの値の設定も恐らく正しく行えたはずですので、プログラムの完成に少し近づけた気がします。
しかし、現状値を一つ入力すると、実行画面が下記のように出力されてしまいます。

数値を入力してください> 24
[ERROR] 数値を再入力してください
hour 0
minute 24
second 24

一度入力した数値が全ての値の範囲内であれば、全て入力されてしまいます…。恐らくは再入力を求める繰り返し文の設定を行なっていない為だと思うのですが、またここからどうしていいのか、お力を貸していただけると助かります。
お手数おかけいたしますが、引き続き何卒よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

Java
java version "1.8.0_161"

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

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

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

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

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

guest

回答2

0

ベストアンサー

質問する際には、必ず実際のエラーメッセージを載せるようにしてください。

インスタンス化ができませんというエラー

Clockをインスタンス化するときに適切な引数を与えていないのが原因です。

Clockのコンストラクタの定義

Java

Clock(int hour, int minute, int second){
this.hour = hour;
this.minute = minute;
this.second = second;
}

こちらでは、int型の引数をみっつ受け取るようなインターフェースになっています。

実際にインスタンス化を試みている箇所

Java

Clock clock = new Clock();

しかし、実際には引数が与えられていません。これが問題です。

#####解消するためには
次の二つのアプローチが考えられます。

  • インスタンス生成時に、適切な引数を渡すようにすること
  • 引数なしのコンストラクタを用意し、各フィールドを適切に初期化すること

clock.setHourに引数がありませんというエラー

同じように、メソッドのインターフェースに沿った呼び出しがされていないからです。

Clock#setHourの定義

Java

public void setHour(int hour) {
this.hour = hour;
}

int型の引数をひとつだけ受け取るように書かれています。

実際にメソッドを呼び出そうとしている箇所

Java

clock.setHour() = Integer.parseInt(str);

これは完全に使い方を誤っていますね。
セッターと言えど、その実態はふつうのメソッドと一緒です。

#####解消するためには
Integer.parseInt(str)の結果を、メソッドの引数として渡してやればいいです。

Java

1clock.setHour(Integer.parseInt(str));

冗長な感がありますが、二行に分けて書くことも出来ます。

Java

1int hour = Integer.parseInt(str); 2clock.setHour(hour);

hourは023,minuteは059,secondは0~59の間の値しか設定できないように制限すること。

これはとりあえずコンパイルエラーを排除してから考えましょう。
いちおうヒントとしては、『セッターの中で値をチェックすれば良い』とだけ言っておきます。

質問追記を受けて

一度入力した数値が全ての値の範囲内であれば、全て入力されてしまいます…。

単に入力を一度しか受け付けていないからかと。

Java

System.out.print("数値を入力してください>" + " ");
String str = br.readLine();

clock.setHour(Integer.parseInt(str));

clock.setMinute(Integer.parseInt(str));
clock.setSecond(Integer.parseInt(str));

時/分/秒について、それぞれ入力を求めるように書き直せば良いんじゃないでしょうか。


もし例外を使うならこんな感じです。

Java

1class Clock { 2 ... 3 4 public void setHour(int hour) { 5 if(hour > 0 && hour <= 23){ 6 this.hour = hour; 7 } else { 8 throw new IllegalArgumentException(); 9 } 10 } 11 12 ... 13}

Java

1while(true){ 2 try{ 3 System.out.print("hourの数値を入力してください>" + " "); 4 String str = br.readLine(); 5 clock.setHour(Integer.parseInt(str)); 6 }catch(IllegalArgumentException e){ 7 System.err.println("[ERROR] 数値を再入力してください"); 8 } 9}

もし返り値を使うならこんな感じです。

Java

1class Clock { 2 ... 3 4 public boolean setHour(int hour) { 5 if(hour > 0 && hour <= 23){ 6 this.hour = hour; 7 return true; 8 } else { 9 return false; 10 } 11 } 12 13 ... 14}

Java

1while(true){ 2 try{ 3 System.out.print("hourの数値を入力してください>" + " "); 4 String str = br.readLine(); 5 6 boolean result = clock.setHour(Integer.parseInt(str)); 7 if(result) { 8 break; 9 } else { 10 System.err.println("[ERROR] 数値を再入力してください"); 11 } 12 }catch(NumberFormatException e){ 13 System.err.println("[ERROR] 数値を再入力してください"); 14 } 15}

投稿2018/05/22 15:38

編集2018/05/28 03:29
LouiS0616

総合スコア35658

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

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

退会済みユーザー

退会済みユーザー

2018/05/22 16:57

早速のご回答ありがとうございます…! ご回答を拝見したところ、自分の理解力不足でぴんときていない点もややあります(申し訳ないです)が、インスタンス化ができないことは中身があると思っていたけれどその実なかったコンストラクタから無理に呼び出そうとしていたことと、やはりsetがうまく使えていないことは理解しました…ご丁寧な解説をいただけて大変ありがたいです。 いただいたアドバイスを元にまた少々考えてみて修正をしようと思います、ありがとうございます!
退会済みユーザー

退会済みユーザー

2018/05/27 14:52

ご指摘いただきありがとうございます。 入力の件、手直ししてみたところうまくいきました!ありがとうございます! 残るは再入力の問題なのですが、while文をつかってみたところ、範囲外の数値を入力すると無限ループから抜け出せなくなってしまいます。何度もお聞きしてしまい恐縮ですが、ご助言頂けませんでしょうか…? 以下Clockクラスの繰り返し文の箇所です。(他は追記したコードと同様の為省略しております) public void setHour(int hour) { while(true){ try{ if(hour > 0 && hour <= 23){ this.hour = hour; break; } } catch(NumberFormatException e) { System.out.println("[ERROR] 数値を再入力してください"); } } }
LouiS0616

2018/05/27 14:55 編集

ループするならば、setHour内ではなく呼び出し元でせねばなりません。 毎周再入力を求める必要がありますので。 例外を既に勉強しているのなら、引数hourが不正なときに例外を投げれば良いです。 まだ習っていないのなら、setHourの返り値をboolean型にして、正常なhourが与えたときにtrue, そうでないときにfalseを返せば代替できます。
退会済みユーザー

退会済みユーザー

2018/05/27 15:39

ご助言いただきありがとうございます。また少し修正いたしました。 ただ、ループ文もいまひとつ理解しかねている部分があるためか、記述がうまくいきません。実行すると正しい値は通り、設定の範囲外の値は0に、そして繰り返し文がきいていない状況です。 引数hourが不正な時に例外を投げる…ということは、whileの()にfalseを使用することかと推測したのですが、 ClockTest.java:11: エラー: この文に制御が移ることはありません while(false){ ^ というエラーが発生してしまい上手くいかず、trueで試してみましたがこちらも同様に上手くいきませんでした。理解不足で読み取ることができず申し訳ありません。またお力を貸していただけますと幸いです。 余談になりますが、例外処理は現在学習途中です。 少々長くなりますが、現状の実行結果、ソースは下記のようになります。 import java.io.*; public class ClockTest { public static void main(String[] args) throws IOException { BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); Clock clock = new Clock(); while(true){ try{ System.out.print("hourの数値を入力してください>" + " "); String str = br.readLine(); clock.setHour(Integer.parseInt(str)); break; }catch(NumberFormatException e){ System.out.println("[ERROR] 数値を再入力してください"); } } // minute, secondも同様の表記のため省略 // System.out.println("hour" + " " + clock.getHour()); System.out.println("minute" + " " + clock.getMinute()); System.out.println("second" + " " + clock.getSecond()); } } 実行結果 hourの数値を入力してください> 15 minuteの数値を入力してください> 89 secondの数値を入力してください> 90 hour 15 minute 0 second 0
退会済みユーザー

退会済みユーザー

2018/05/27 15:43

Clockクラスも少々変更したため、こちらに掲載させていただきます。やや見辛くなってしまって申し訳ありません。修正したコードは下記の通りとなります。 // Clockクラス public class Clock { private int hour; private int minute; private int second; //コンストラクタ1 public Clock(){ super(); } //コンストラクタ2 Clock(int hour, int minute, int second){ this.hour = hour; this.minute = minute; this.second = second; } //SET public void setHour(int hour) { if(hour > 0 && hour <= 23){ this.hour = hour; } } public void setMinute(int minute) { if(minute > 0 && minute <= 59){ this.minute = minute; } } public void setSecond(int second) { if(second > 0 && second <= 59){ this.second = second; } } //GET public int getHour(){ return hour; } public int getMinute(){ return minute; } public int getSecond(){ return second; } }
LouiS0616

2018/05/28 03:30

回答にイメージを追記しておきました。
退会済みユーザー

退会済みユーザー

2018/05/28 14:15

返信遅くなりました。 コードのイメージの追記をいただき、ありがとうございます。 返り値のイメージの方を元に修正したところ、行いたかったこと通りの動作ができました! 沢山お聞きしてしまったのに、最後までお付き合いいただけて本当にありがとうございます。また一つ勉強になりました。 根気強く面倒見てくださったLouiS0616さんにベストアンサーをお贈りいたします、改めましてありがとうございました!
guest

0

こんにちは、
引数が時、分、秒であるクラスにしました。
時、分、秒をそれぞれ入力し、それをもとに時刻を表示します。

質問欄にあるソースコードを見て気になったところ

java

1 if ((clock.getHour() > 0) && (clock.getHour() <= 23)) { 2 System.out.println(clock.getHour()); 3 4 } else if ((clock.getMinute() > 0) && (clock.getMinute() <= 59)) { 5 System.out.println(clock.getMinute()); 6 7 } else if ((clock.getSecond() > 0) && (clock.getSecond() <= 59)) { 8 System.out.println(clock.getSecond()); 9 } 10

とありますが、else ifではなくすべてただのifです。
例えば、「時」を入力するとき12を入力すると最初のif文はになるので、それ以降のelse ifは実行されません。

私が書いたコードでは配列とfor文を使ったループ処理で判定を行っています。

Java

1import java.io.*; 2import java.util.*; 3 4public class Midi{ 5 public static void main(String[] args) throws IOException { 6 7 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 8 9 try{ 10 11 String []text = {"hour","minute","second"}; 12 int []limit = {24,60,60}; 13 int []time = new int[3]; 14 boolean []judge = new boolean[3]; 15 16 for(int i = 0; i < time.length; i++){ 17 System.out.println(text[i] + "の数字を入力してください。"); 18 do{ 19 String str = br.readLine(); 20 time[i] = Integer.parseInt(str); 21 if(0 <= time[i] && time[i] < limit[i]){ 22 judge[i] = false; 23 } 24 else{ 25 judge[i] = true; 26 System.out.println("再入力してください。"); 27 } 28 }while(judge[i]); 29 } 30 31 32 Clock clock = new Clock(time[0],time[1],time[2]); 33 clock.print_time(); 34 35 } 36 catch(InputMismatchException e){ 37 System.out.println("数字を入力してください。"); 38 } 39 } 40} 41 42class Clock{ 43 44 private int hour; 45 private int minute; 46 private int second; 47 48 public Clock(int Hour, int Minute, int Second){ 49 this.hour = Hour; 50 this.minute = Minute; 51 this.second = Second; 52 } 53 public void print_time(){ 54 System.out.println(hour + "時" + minute + "分" + second + "秒"); 55 } 56}

投稿2018/05/23 03:54

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2018/05/27 13:44

確認、返信が遅くなってしまい申し訳ございません。 ご丁寧な回答ありがとうございます。こういった記述の仕方もあるのだとまたひとつ勉強になりました、毎回ご回答いただきまして大変助かります。今後の参考にさせていただきます。ありがとうございます…!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問