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

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

ただいまの
回答率

90.03%

コンストラクタを使って....

受付中

回答 5

投稿 編集

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

aikosu

score 10

■円の面積と円周の長さを出力したい

・クラスを作成しコンストラクタで半径と円周率を設定
・半径と円周率に数字以外が入力された場合NG
・半径と円周率二数値以外が入力された場合メッセージ出力
・円周率が入力されなかった場合、クラス定数を代入
・円周の値は小数第2位までの出力

コンストラクタを設定するメリットは?

package en12;

public class Circle {
private double pi, radius;
final double PI = 3.14;

public Circle(double radius) {
this.pi=3.14;
}

public double getPi() {
return pi;
}

public void setPi(double pi) {
this.pi = pi;
}

public double getRadius() {
return radius;
}

public void setRadius(double radius) {
this.radius = radius;
}

public Circle(double radius, double pi) {
super();
this.radius = radius;
this.pi = pi;
}

void area() {
double s = radius * radius * pi;
double l = radius * 2 * pi;
System.out.print(s);
System.out.println(l);
}
}

package en12;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Ex0512 {

public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
System.out.print("半径>");
String str = br.readLine();
double r = Integer.parseInt(str);
try {
System.out.print("円周率>");
String str1 = br.readLine();
double p = Integer.parseInt(str1);
Circle B = new Circle(r, p);
Circle C = new Circle(r);
System.out.println("面積:"+(r*r*p));
} catch (NumberFormatException e) {
System.out.println("円周は数値を入力してください");
}
} catch (NumberFormatException e) {
System.out.println("半径は数値を入力してください");
}
}
}

わからない...

あと円周率入力の際小数を入力した場合で例外処理が行われてしまいます.......

円周率>5.0

でもOKにしたいのですが....

■円周で何も入力しなかった場合
3,14が適用されるコードって......

メインで円周率を入力し無かった場合
円周率に3.14が代入されるようにするには
どうすればよいですか?

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 5

+2

変更不可能(immutable)なオブジェクトとして作成する場合は、コンストラクタ以外で半径や円周率を設定することができません。immutableなオブジェクトの利点や欠点は長くなるので省きますが、そのようなオブジェクトを作るクラスの設計としては、コンストラクタで全て設定することはなんら不思議ではない、むしろ、そうせざるを得ないことです。

設計としては、円クラスを用意して、そのクラスから円オブジェクトを作成し、その性質(半径以外にも、円周の長さや面積など)を取り出すというものだと思います。この方法はオブジェクト指向で設計する場合は何ら不思議なものではありません。オブジェクト指向とは、あるデータのまとまりを一つにまとめた一つのオブジェクトにすることで、そこからプロパティを得たり、関連するオブジェクトを生成する、何らかの動作を起こすものです。二つ以上の常に揃って連携するデータをなんらかのクラスでまとめて扱っていない場合、オブジェクト指向の考え方で作られていない設計と言えます。必要であるかどうかの問題ではありません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

+1

何らかの課題と思われるので、お題の「円」ではなくRPGなどのキャラクターを例に説明します。
コンストラクタを設定するメリットは

  • 初期化するパラメータの入力を強制できる
    次のようなクラスを考えると
class Chara {
    int hp;

    public static void main(String[] args) {
        Chara c = new Chara();
    }
}

このようにしてインスタンス生成はできることはできますが、hpが0の状態で生成されることになり、いきなり倒れます。インスタンス生成後にフィールドの値を設定する必要が生じるので、使う側がその初期化を忘れると意図しない動作の原因になります。コンストラクタを設定した場合、

class Chara {
    int hp;

    Chara(int hp) {
        this.hp = hp;
    }

    public static void main(String[] args) {
        // Chara c = new Chara();  コンパイルエラー!
        Chara c = new Chara(10);
    }
}

hpの初期値を引数を持ったコンストラクタを作成すると、引数なしのコンストラクタが(このままだと)存在しない状態になります。引数なしのコンストラクタを使おうとするとコンパイルエラーとなるため、ミスに早い段階で気づくことができます。Charaクラスを使うためにhpの初期値を入力することを強制されるため、意図しない状態でのCharaインスタンスの運用を減らすことができます。

  • finalフィールドの初期値・デフォルト値設定
    前の方の回答で不変オブジェクトの話が出ていますがそれ関係で、クラスのフィールドの中で「一度設定したら変更したくない」というものも設定する必要がある場合があります。Charaのhpは変動するのが前提なので例としては適しませんが、仮にhpをfinalにしたとします。
class Chara {
    final int hp;

    Chara(int hp) {
        this.hp = hp;
    }

    public static void main(String[] args) {
        Chara c = new Chara(10);
    }
}

これでも使えることは使えるのですが、ここで「初期値入力がない場合にhpは5としておきたい」という要求があったとします。この時、finalのフィールド宣言時にfinal int hp = 5;のようにしてしまうと、今度はコンストラクタでの値の設定ができなくなってしまいます(コンパイルエラー)。
そのため、引数なしのコンストラクタを用意し、あたかも初期値に5を与えてコンストラクタを使用したようにできます。

class Chara {
    final int hp;

    Chara(int hp) {
        this.hp = hp;
    }

    Chara() {
        this(5);
    }

    public static void main(String[] args) {
        Chara c = new Chara(10);
    }
}

Integerは「整数」という意味です。小数は扱えません。doubleにしたいならDouble.parseDouble()を使ってください。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/09/03 16:14

    package en12;

    public class Circle {
    private double pi, radius;
    final double PI = 3.14;

    public Circle(double radius) {
    this.pi=3.14;
    }

    public double getPi() {
    return pi;
    }

    public void setPi(double pi) {
    this.pi = pi;
    }

    public double getRadius() {
    return radius;
    }

    public void setRadius(double radius) {
    this.radius = radius;
    }

    public Circle(double radius, double pi) {
    super();
    this.radius = radius;
    this.pi = pi;
    }

    void area() {
    double s = radius * radius * pi;
    double l = radius * 2 * pi;
    System.out.print(s);
    System.out.println(l);
    }
    }

    キャンセル

  • 2017/09/03 16:16

    まだ途中なのですが....
    円周率を入力しなかった場合、3.14が自動で使用になるコードがわかりません.....

    キャンセル

  • 2017/09/03 16:20

    円周率を入力しなかった場合、piには定数PIを入れればいいだけの話です。
    あと、コンストラクタはコンストラクタで場所をまとめましょう。

    キャンセル

0

コンストラクタどころか専用クラスを定義する必要性すらありません。普通にエントリポイントのためのクラスがひとつあれば実現できます。

多分、課題の情報が欠けています。そもそも円周率を都度都度入力する必要性がわかりません。しかも定数を用意しておくならば、なおさら用途不明です。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

そもそもクラスを作る必要がない、という点では完全に同意です。
その上で、もし無理矢理クラスを作るなら、以下の点で違いはあると思います。

コンストラクタがない
正確には、引数のないコンストラクタを用いる場合。
流れ) インスタンスを生成、半径を設定、円周を取得
問題点) 半径を設定する前に円周が取得されようとした場合どうする?

コンストラクタがある
正確には、適宜引数を取るコンストラクタを用いる場合。
流れ) インスタンスを生成(同時に半径を設定)、円周を取得

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

引数付きコンストラクタを敢えて作る理由としては、
・一度作成したクラスの(コンストラクタで指定した)属性を変更させたくない
場合です。
今回の例で言えば、円の半径と円周率は、作ったが最後固定される、というのを保証するための方法の一つです。
※ゲッターしかない属性に対して初期値を与えるためにコンストラクタを使う

ただし、これが課題だとすると、そもそもJavaのコンストラクタなのですから、数値型でパラメータを定義すれば、数値以外を受け取る、という事自体があり得ません。従って NG を表示するも何もない(そもそもコンパイルが通らない)です。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

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