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

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

ただいまの
回答率

90.76%

  • Java

    13157questions

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

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 235

Terra.

score 7

 前提・実現したいこと

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

 問題文

下記クラスにあるフィールドをprivateにした上で、外部から値を設定したり取得できるように変更しなさい。
ただしhour0~23,minute0~59,second0~59の間の値しか設定できないように制限すること。
それ以外の値を設定しようとした場合のエラー文言は任意とする。

使用前提条件のクラス:

public class Clock{
    int hour;
    int minute;
    int second;
}

 作成途中のソースコード

// Clockクラス //

public class Clock {
        private int hour;
        private int minute;
    private int second;

     //コンストラクタ
        Clock(int hour, int minute, int second){  
                this.hour = hour;
                this.minute = minute;
                this.second = second;
        }

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

        public void setMinute(int minute) {
            this.minute = minute;
        }

        public void setSecond(int second) {
            this.second = second;
        }

        //GET
        public int getHour(){
            return hour;
        }

        public int getMinute(){
            return minute;
        }

        public int getSecond(){
            return second;
        }

}


// Clockクラスを外部から実行するための別クラス、ClockTestクラス //


import java.io.*;

public class ClockTest {
    public static void main(String[] args) throws IOException {

    try{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

        Clock clock = new Clock(); 

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

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

        // 範囲チェック
        if ((clock.getHour() > 0) && (clock.getHour() <= 23)) {
            System.out.println(clock.getHour());

        } else if ((clock.getMinute() > 0) && (clock.getMinute() <= 59)) {
            System.out.println(clock.getMinute());

        } else if ((clock.getSecond() > 0) && (clock.getSecond() <= 59)) {
            System.out.println(clock.getSecond());
        }

        } catch(Exception e) {
            System.out.print("[ERROR] 数値を再入力してください>" + " ");
        }

    }
}

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

// 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;
         /*
             } else {
            System.out.println("[ERROR] 数値を再入力してください");
        }
               */
        }

        public void setMinute(int minute) {
            if(minute > 0 && minute <= 59){
            this.minute = minute;
         /*
            } else {
            System.out.println("[ERROR] 数値を再入力してください");
        }
               */
        }

        public void setSecond(int second) {
            if(second > 0 && second <= 59){
            this.second = second;
         /*
            } else {
            System.out.println("[ERROR] 数値を再入力してください");
        }
               */
        }

        //GET
        public int getHour(){
            return hour;
        }

        public int getMinute(){
            return minute;
        }

        public int getSecond(){
            return second;
        }

}



// Clockクラスを外部から実行するための別クラス、ClockTestクラス //


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();

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

        clock.setHour(Integer.parseInt(str));
        clock.setMinute(Integer.parseInt(str));
        clock.setSecond(Integer.parseInt(str));
*/

//冗長かもしれませんが、入力の仕方を一つずつ入力できるよう修正しました

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

        System.out.print("minuteの数値を入力してください>" + " ");
        str = br.readLine();
        clock.setMinute(Integer.parseInt(str));

        System.out.print("secondの数値を入力してください>" + " ");
        str = br.readLine();
        clock.setSecond(Integer.parseInt(str));

        try{
            System.out.println("hour" + " " + clock.getHour());
            System.out.println("minute" + " " + clock.getMinute());
            System.out.println("second" + " " + clock.getSecond());

        } catch(Exception e) {
            System.out.println("[ERROR] 数値を再入力してください");
        }

    }
}

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

実行(したい)画面例

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"

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+4

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

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

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

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

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

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

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

Clock clock = new Clock();

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

解消するためには

次の二つのアプローチが考えられます。

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

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

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

Clock#setHourの定義

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

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

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

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

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

解消するためには

Integer.parseInt(str)の結果を、メソッドの引数として渡してやればいいです。

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

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

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

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

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

質問追記を受けて

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

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

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

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

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


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

class Clock {
    ...

    public void setHour(int hour) {
         if(hour > 0 && hour <= 23){
             this.hour = hour;
         } else {
             throw new IllegalArgumentException();
         }
    }

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

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

class Clock {
    ...

    public boolean setHour(int hour) {
         if(hour > 0 && hour <= 23){
             this.hour = hour;
             return true;
         } else {
             return false;
         }
    }

    ...
}
while(true){
    try{
        System.out.print("hourの数値を入力してください>" + " ");
        String str = br.readLine();

        boolean result = clock.setHour(Integer.parseInt(str));
        if(result) {
            break;
        } else {
            System.err.println("[ERROR] 数値を再入力してください");
        }
    }catch(NumberFormatException e){
         System.err.println("[ERROR] 数値を再入力してください");
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/23 01:57

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

    キャンセル

  • 2018/05/27 23: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] 数値を再入力してください");
    }
    }
    }

    キャンセル

  • 2018/05/27 23:55 編集

    ループするならば、setHour内ではなく呼び出し元でせねばなりません。
    毎周再入力を求める必要がありますので。

    例外を既に勉強しているのなら、引数hourが不正なときに例外を投げれば良いです。
    まだ習っていないのなら、setHourの返り値をboolean型にして、正常なhourが与えたときにtrue, そうでないときにfalseを返せば代替できます。

    キャンセル

  • 2018/05/28 00: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/28 00: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;
    }

    }

    キャンセル

  • 2018/05/28 12:30

    回答にイメージを追記しておきました。

    キャンセル

  • 2018/05/28 23:15

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

    キャンセル

+1

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

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

       if ((clock.getHour() > 0) && (clock.getHour() <= 23)) {
            System.out.println(clock.getHour());

        } else if ((clock.getMinute() > 0) && (clock.getMinute() <= 59)) {
            System.out.println(clock.getMinute());

        } else if ((clock.getSecond() > 0) && (clock.getSecond() <= 59)) {
            System.out.println(clock.getSecond());
        }


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

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

import java.io.*;
import java.util.*;

public class Midi{ 
    public static void main(String[] args) throws IOException {

        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

        try{

             String []text = {"hour","minute","second"};
             int []limit = {24,60,60};
             int []time = new int[3];
             boolean []judge = new boolean[3];

             for(int i = 0; i < time.length; i++){
                 System.out.println(text[i] + "の数字を入力してください。");
                 do{
                     String str = br.readLine();
                     time[i] = Integer.parseInt(str);
                     if(0 <= time[i] && time[i] < limit[i]){
                         judge[i] = false;
                     }
                     else{
                         judge[i] = true;
                         System.out.println("再入力してください。");
                     }
                 }while(judge[i]);
             }


             Clock clock = new Clock(time[0],time[1],time[2]); 
             clock.print_time();

        }
        catch(InputMismatchException e){
            System.out.println("数字を入力してください。");
        }
    }
}

class Clock{

    private int hour;
    private int minute;
    private int second;

    public Clock(int Hour, int Minute, int Second){
        this.hour = Hour;
        this.minute = Minute;
        this.second = Second;
    }
    public void print_time(){
        System.out.println(hour + "時" + minute + "分"  + second + "秒");
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/27 22:44

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

    キャンセル

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

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    会員情報システム(Java)での作り方

    javaで会員情報システムのようなものを作りたいです。 下記の実行結果(コマンドプロンプトで実行)になるような、登録プログラムを作成したいのですが、作成方法が分かりませんので、教

  • 解決済

    Javaでの文字コード値取得について

    Javaでutf-8のコード値からunicodeに変換するにはどうすればいいでしょうか? public static void main(String[] args) {

  • 解決済

    類似度を使ったクラスタリング法

    実現したいこと IaaSクラウドオントロジクラスタリングに関するシステムを作っています 要素(elem)と要素(elem) 要素(elem)とクラスタ(cluster)

  • 解決済

    javaで文字列に格納した時刻を数値として受け取る方法

    下に記述したように、stringの時刻を、時間と分を別々にint型の変数に入れたいのですが、どのようにすると良いのでしょうか? private static String[] t

  • 解決済

    java 配列を別クラスで受け取る方法

    キーボードから入力したテストの結果から、合計・平均・順位(バブルソート)分散・標準偏差を導出するプログラムを作っています。 具体的には 生徒数を入力 ↓ 生徒数の応じた点数を入力

  • 解決済

    java整数以外を...

    package en11; import java.io.BufferedReader; import java.io.IOException; import java.io.

同じタグがついた質問を見る

  • Java

    13157questions

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