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

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

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

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

Q&A

解決済

5回答

893閲覧

コンストラクタの役割、説明

rin_rin0000

総合スコア8

Java

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

1グッド

1クリップ

投稿2018/08/09 14:26

編集2018/08/09 14:30

java SE8
コンストラクタの仕組みがいまいちわからないままプログラミングをしています。
コンストラクタってなにが便利なのか?なんで使うのか??いらないんじゃない??
とか思ってしまいます
ちなみにカプセル化の理解度も低めです。 下記はカプセル化できていると思いますがあっていますか?

コンストラクタ意味を調べたのですが初期化するとか定義するとか書いてあって頭の悪い私では理解できなかった為、わかりやすい説明を求めます。
ちょっとしたソースコード例を記載するのでそれを説明に入れてもらっても大丈夫です。
小学生でも理解できるように教えてもらえれば幸いです。宜しくお願いします。

class Card
class CardNumber

2ファイルで記載します

public class Card { public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ CardNumber card = new CardNumber("キング", 10, 3); String str = card.getName(); int n = card.getNumber(); int s = card.getSheets(); System.out.println(str); System.out.println(n); System.out.println(s); } }

public class CardNumber { private String name; private int number; private int sheets; public CardNumber(String name,int number, int sheets) { this.name = name; this.number = number; this.sheets = sheets; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public int getSheets() { return sheets; } public void setSheets(int sheets) { this.sheets = sheets; }

以上です。
宜しくお願いします。

※ 余談ですがGithubとかSlackって流行っているんですね

fa11enprince👍を押しています

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

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

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

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

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

swordone

2018/08/09 14:40

sheetsではなくsuitsでは?
guest

回答5

0

コンストラクタが便利なのではありません。
クラスが便利なのです。

クラスとは小さな「データとアルゴリズムの集まり」であり、単体で完結する「小さなプログラム」でもあります。
例えばいわゆるトランプのカードのクラスを例に取れば、カードには
・数値(A,2~10,J,Q,K)
・マーク(スペード・ハート・ダイヤ・クラブ)
・自身が「表か裏か」
があり、また行える操作として
・裏返す
・数値を返す(裏なら分からない)
・マークを返す(裏なら分からない)
・自身を表示する(表裏によって表示が異なる)
といった操作が行えるでしょう。

しかしよく考えてください。カードは一度作成したら、数値もマークも変化しませんね?(マジシャンがマジックで使うのは別ですが)
ということは、数値にせよマークにせよ、「作る時に決まれば、あとは変更させない」方がよくなります。
そこで「カードを作る時に数値とマークを設定すればいい」となり、そのためにコンストラクタが活躍します。

まずはクラスをはじめとするオブジェクト指向の基礎をしっかりと学びましょう。

投稿2018/08/09 14:44

tacsheaven

総合スコア13703

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

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

rin_rin0000

2018/08/11 14:13

まずはクラスをはじめとするオブジェクト指向の基礎をしっかりと学びましょう。ということでしっかりとオブジェクト指向の基礎を学び、理解した上で多言語もどんどん学んで使えるように頑張ります!ありがとうございました。
guest

0

ベストアンサー

コンストラクタの役割としては、クラスの初期化(初期状態の決定)で良いと思います。

提示のCardNumberクラスの前提条件としてname, number, sheetsが必ず指定されていないといけない場合はコンストラクタで設定させるようにクラス設計します。

引数なしのコンストラクタでインスタンス化(new CardNumber())した後にsetterで値をセットする方法だと、setterでセットし忘れたり、複数人で開発する場合にルールを守らない人が出てきて、中途半端な状態のCardNumberインスタンスが存在してしまう可能性が出てきてしまいます。(nameの無いCardNumberとか)

下記はカプセル化できていると思いますがあっていますか?

文法上はカプセル化出来ていますが、用途から考えた場合はカプセル化出来ていないかもしれません。
例えばCardNumberクラスのインスタンスは実際のカードと同じ用途のため、「インスタンス化した後に内容を変更させない」場合は以下のように色々と外からのアクセスを制限(カプセル化)します。

Java

1 2public class CardNumber { 3 private String name; 4 private int number; 5 private int sheets; 6 7 private CardNumber() { 8 // 引数なしでインスタンス化されることを防ぐ 9 throw new AssertionError(); 10 } 11 12 public CardNumber(String name,int number, int sheets) { 13 this.name = name; 14 this.number = number; 15 this.sheets = sheets; 16 } 17 18 public String getName() { 19 return name; 20 } 21 22 public int getNumber() { 23 return number; 24 } 25 26 public int getSheets() { 27 return sheets; 28 } 29 30 // カードの内容を変更させないため 31 // setterは提供しない 32 33 34 // CardNumberに行えるアクション(裏返す、向きを変えるなど)は 35 // publicメソッドとして実装する 36

投稿2018/08/09 15:06

takyafumin

総合スコア2335

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

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

0

クラスを使う側の立場に立って考えると理解しやすいかもしれません。
カプセル化にかかわることなのですが、オブジェクト指向の本質の一つはそのクラスを使う側が使いやすいようにして、間違った使い方をしないようにする、ということです(もちろんこれは一つの側面に過ぎないのですが)。
それであまりいい例が思い浮かばなかったのですが、古くからあるJavaの標準ライブラリのjava.io.Fileクラスだと、

java

1import java.io.File; 2 3public class MyClass { 4 public static void main(String args[]) { 5 File file = new File("C:/tmp/text1.txt"); // C:\tmp\text1.txtでも良いが、こちらがおすすめ(/はWindows/Linuxで通用する) 6 if (file.exists()) { // ファイルがあるか? 7 System.out.println("file exists."); 8 file.delete(); // ファイルを消す 9 } else { 10 System.out.println("file is not found."); 11 } 12 System.out.println(file.getParent()); // 一つ上の階層のパスを表示 => C:/tmp 13 } 14}

という感じで使って、コンストラクタで一旦パスを設定する。
そのあと、そのファイル(またはディレクトリ)に対して、やりたい操作(メソッド)を呼び出す。
という使い方になります。

上記のようにコンストラクタでファイルの場所を指定します。
もし、コンストラクタがなければ、

java

1File file = new File(); 2file.setPath("C:/tmp/text1.txt");

と冗長になってしまいますし、
途中で、file.setPath("C:/tmp/text2.txt");と誤って書き換えることがあるかもしれません。

一旦パスを指定すれば、あとはexists()メソッドで存在を確認したり、delete()メソッドでそのパスのもの(ファイルやディレクトリ)を消すことができます。
逆にsetPath()のようなメソッドはなくて、使う側にむやみやたらに無用にパスなどを書き換えられないようにカプセル化して、クラスの詳細を知らずとも、とりあえずこれを使えばこういうことができる、というようにクラスが設計されています。

実際のソースコードはこんな感じで、知らなくてもよい(または外から書き換える必要がない)ようなものはprivateになっています。
Open JDK 1.8 Fileクラス

備考: 今回の件とは関係ないですが画面などユーザの目に触れる部分ではC:/tmp/text1.txtのようなスラッシュ表記は使ってはいけないです。参考

あと、カプセル化に関してですが、
フィールドすべてにgetter/setterをつけるなら最初からすべてフィールドをpublicにしてしまえば実はよいのです(ただし、getXXX()/setXXX()があるのを前提としているフレームワーク等が存在するので伝統的にそうしていることが多いです。このあたりはJavaBeansというのが背景にあって、興味があれば調べてみてください(もう知らなくてもいいかもしれません))。最近だとこの辺りは非常にだるいのでLombokというライブラリで逃げます。

オブジェクト指向が一般的になってから出始めた言語なのでこの辺りは結構古い思想でできてしまっています。ちなみにRubyやPythonだと基本public扱いでフィールドを露出したままのことが多いです(言語仕様的にやりにくいし、思想的に不要というのもある)。

要は、カプセル化は、使う側の人が明示的に書き換える必要のないものはprivateにして書き換え不可にしてしまって、最小限の情報だけ開示するってものです。この辺まともに説明している書籍は昔はあまりなかったです。

余談ですが、あまりコンストラクタを提供するパターンのクラスを見ないぞ?と思って、かつこの辺が理解できましたら、デザインパターンを勉強してみてください。

投稿2018/08/09 18:20

編集2018/08/11 14:53
fa11enprince

総合スコア45

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

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

rin_rin0000

2018/08/11 14:12

java.io.Fileクラスを使っての説明をしていただきありがとうございます。ファイル入出力filereader等で使用することが多々あるので合わせて学ばせていただき勉強になりました。
guest

0

カプセル化に関して答えます。
カプセル化は変数名を変えると利用されるクラスに想定される影響を考慮されて作られたものではないかと考えています。

ソース1はソース2を抜粋したものです。コメントの意味を考えてください。

///ソース1 private static String name;///この名前をname_1にするとした時を考えてみると?① static String name2;//この名前をname_2にするとtest2クラスはどうなる?②

①特に何の影響もない
②test2クラスがコンパイルエラー
となります。

余談なんですけど久しぶりにEclipse起動してJava書いてたら細かい文法の制約多すぎやなと思いました。
そのてんPythonはいいね。
そもそもEclipse起動したのJavaSilverの勉強して以来なんやけど・・・

///ソース2 package test; public class test{ private static String name;///この名前をname_1にするとした時を考えてみると? static String name2;//この名前をname_2にするとtest2クラスはどうなる? public static String getName() { return name; } public static void SetName(String name) { return name = name ; } } class test1{ String name = test.getName(); } class test2{ String s = test.name2; }

投稿2018/08/09 15:41

編集2018/08/09 15:58
flan

総合スコア146

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

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

rin_rin0000

2018/08/11 14:10

ソース例を挙げていただきありがとうございました。現在java silver参考書を購入し資格へ向けて勉強中です。pythonもjavaが使えるようになったら勉強していきたいと思っています。
guest

0

コンストラクタが無ければ以下のように書かねばならず面倒臭いからです。

java

1CardNumber card = new CardNumber(); 2card.setName("キング"); 3card.setNumber(10); 4card.setSheets(3);

投稿2018/08/09 14:37

hichon

総合スコア5737

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問