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

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

ただいまの
回答率

90.86%

  • C#

    6244questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

クラスとインスタンス

解決済

回答 6

投稿

  • 評価
  • クリップ 1
  • VIEW 400

MitzKuno

score 3

C#を独学で学んでいる者です。
わからない部分が出てきたので、ご教授願います。
もしかしたら以前の質問と重複してしまう部分があるかもしれませんが、お手柔らかにお願いします。

『UnityではじめるC#』という入門書で下記のプログラミングを打ちました。

using UnityEngine;
using System.Collections;

public class Lesson1 : MonoBehaviour {

    // Use this for initialization
    void Start () {
        Person p = new Person ();
        p.name = "太郎";
        p.show ();
    }

    // Update is called once per frame
    void Update () {

    }
}

class Person
{
    public string name;

    //ここは省略されていると前回の質問で知りました。
    public Person () {
        return;
    }

    public void show () {
        Debug.Log("私の名前は" + this.name);
    }
}

これで、プログラミング下部のPersonクラスのインスタンスを作ろうという項目を学んでいたのですが、入門書ではプログラミングを打ってエラーが無かったら次に行くという感じで項目が終わってしまい、肝心のなぜこうなるという説明が無く、いまいち何を学んだのかわかりませんでした。
そこで今回、理解できなかった点を絞り、具体的に質問したいのは以下の4点です。

1.Personクラスを作った後、StartメソッドでPerson()(コンストラクタ?)にnew演算子を付けて、Person型・変数pに代入したのは、なぜなのでしょうか?
入門書では、C#はクラスを設計図として、そのクラスから作った実体のことをインスタンスというと書かれてあり、このプログラミングが最終的に示す答えとして「私の名前は太郎」となる経緯を打った式だと思うのですが、

まずPersonクラスを作り
public string nameというメンバー変数を打ち
そのあとなぜクラスをインスタンス化させるnew演算子をPerson()に付けたのでしょうか、これが理解できませんでした。
その後は、Personクラスを型として変数pにnew Person ()を代入するということだったと思います。

2.またその後、変数pとメンバー変数nameをドット演算子でくっつけているのですが、これは変数pがクラス、メンバー変数nameがメソッドとなり、nameメソッドがpクラスの中で定義されているという解釈で正しいでしょうか?

3.showメソッドとは、どのような用途なのでしょうか?インターネットで調べても機械翻訳で書かれた説明文しか見つからず、機械翻訳の説明では読んでもわけがわかりませんでした。

4.最後にp.show ();がStartメソッド内で、showメソッドがPersonクラス内で書かれているのですが、これにはどんな意味があるのでしょうか?
なぜp.show ();が上で、showメソッドが下なのか。逆ではだめな理由などがあるのでしょうか

以上が入門書を読んでいてもわからなかった点になります。
質問が多過ぎると思うのですが、どうか助けていただけると幸いです。
何卒よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 6

+4

他の方が詳しくプログラムの話をしているので、補足として「概念」の話をしますね。

あなたは神様です。
これから人間(Person)を作ろうとしています。

①まず、人間とはどんな要素を持っているでしょうか。神様はこう考えました。
「人間には1人1人、個別の名前を持たせよう」
名前を格納する領域としてpublic string name;を作りました。

②引き続き人間の要素を考えます。
show()と呼びかけたら、私の名前は〜と名前を答えさせるようにしよう」
public void show () {〜}を作りました。
showという単語自体に意味は無く、showメソッドを呼んだらこういう挙動をする決めただけ)

とりあえず人間の要素はこれでいいことにします。
では実際の人間を作りましょう。

new Person();
この1行で世界に1人の人間が出現します。これはこの世界(C#)の決まりです。
しかしこれだけだと人間は神様の手から離れてしまっています。
この人間をどうこうしたい場合、また捕まえないといけません。それはちょっと面倒です。
Person p = new Person();
なのでこう書くと、「pとは今作った人間のことですよ」と定義することが出来ます。

神様はpに名前を与えることにしました。
「今作った人間、お前の名前は"太郎"だ」
これをコードにするとp.name = "太郎";になります。
なぜなら人間の構成要素の中でnameとは名前であるというルールを①で決めたので、それに則っています。

神様はpに名前を聞いてみることにしました。
「今作った人間、お前の名前は何だ?」
これをコードにするとp.show();です。
なぜなら人間の構成要素の中でshow()と呼びかけられたら私の名前は〜と表示するというルールを②で決めたので、それに則っています。


これにより、神様は自由に人間を作れるようになりました。
名前だけでなく「年齢」という要素を付けたいならpublic int age;を加えればいい。
名前を答えるだけでなく歩かせたいならpublic void walk () {〜}を加えればいい。
太郎だけで足りなかったら花子やジョンを作ればいい。

ではそもそも、なぜ人間を作る必要があるんでしたっけ?
それを決めるのも神様の仕事です。

動物が出るゲームならAnimalを作ればいい。
味方と敵が出るゲームならPlayerとEnemyを作ればいい。
音を管理するモノが必要ならMusicControllerを作ればいい。

これをこの世界の用語で「設計」と言います。

他、今回使ったイメージとプログラム用語の対応表です。

人間の構成要素(Person)=「クラス」
生まれ落ちた人間(new Person()、広義ではpも)=「インスタンス」
人間の名前(name)=「メンバー変数 または プロパティ」
人間の名前を表示する機能(show)=「メソッド」
初期化時に呼ばれるメソッド(public Person () {})=「コンストラクタ」


重要なのは「何がルールで、何が自分で決めるものなのか」という点です。
今回の例なら、インスタンス作成時にnew Person();とするのはルール(「こう書くとこう動く」というC#の仕様)。
Personクラス内のpublic Person () {〜}が初期化時勝手に呼ばれるのもルール。
一方でshow()は自分で作った(決めた)メソッド。神様が呼ぶ(ような仕組みを作る)までは呼ばれません。

「1.どんなルールがあるのか」
「2.どう自分で決めるか(=どうルールを利用して効率的な物を作るのか)」
この両方が「プログラムの勉強」に当たります。
最初は見極めが難しいと思いますが、自分で手を動かしたり色々な資料を見ていると段々分かってきます。

Unityの場合なら、まずリファレンスを見ると「ルール」が分かりますのでこちらも参考にすると良いかと。
Unity スクリプトリファレンス

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/14 13:18 編集

    最後に皆さんの概念を統括して体系化して物語で語ってくださり、ありがとうございました。
    読み終えて「そういうことか」と掌をグーで叩けました。

    今は私自身、学んでいる段階であり、今後、sakura_hanaさんのいう「何がルールで、何が自分で決めるものなのか」という点でまたいろいろな壁にぶち当たると思うのですが、まずは今の疑念が晴れて入門書の次のページを進められることに気分が高揚している次第です。
    解答してくださり、ありがとうございました。

    キャンセル

  • 2018/07/14 14:05

    あと『Unityスクリプトリファレンス』を教えてくださり、ありがとうございました。
    これでC#における”ルール”の部分を自身で把握することができるようになりました。

    キャンセル

checkベストアンサー

+3

まず前提として、このコードの動作は
「私の名前は太郎」
と表示するだけなので、こう書いても同じ動きをします。

public class Lesson1 : MonoBehaviour {

    // Use this for initialization
    void Start () {
        Debug.Log("私の名前は太郎");
    }

    // Update is called once per frame
    void Update () {

    }
}

なので、なぜPersonクラスを作ったかといえば、人間の都合(読みやすい、後々の拡張性、など)のためで、
そう書かないと動かないからではありません。


1.Personクラスを作った後、StartメソッドでPerson()(コンストラクタ?)にnew演算子を付けて、Person型・変数pに代入したのは、なぜなのでしょうか?
まずPersonクラスを作り
public string nameというメンバー変数を打ち
そのあとなぜクラスをインスタンス化させるnew演算子をPerson()に付けたのでしょうか、これが理解できませんでした。

恐らく、クラスとインスタンスのイメージになにか誤解があるのだと思います。

class Person{
    ...
}


で、あなたが一生懸命キーボードを打ったそれは、あくまで"型"であって、
具体的な個々の"値"ではありません。

型という観点から見れば、Personは、intstringと同列の概念です。
例えば、

string s = "nice text";


と書かれていて、「なぜstring型の変数にわざわざ値を代入したんだ?」とは思わないでしょう。
Personも一緒です。

ただ、string型については、特別にC#が気を利かせて、
"nice text"と書くだけでstring型の値を生成できるようになってますが、
Person型にはそれがないので、Person型の値(Person型のインスタンス)を
new Person()とコンストラクタを書いて生成しています。

実はstringもクラスなので、コンストラクタがあります。
こう書くと

string s = new string(new char[]{'a','b','c'},0,3);
string s = "abc";


と同じ結果が得られます。(Unityでもできるかどうかはわかりませんが。)

実際stringはあなたのPersonと同じように宣言されたもので、実装がここにあります。
内容は難しいので別に理解する必要はないんですが、
何気なく使ったstringが実はPersonと同じ文法で作られたものだということがわかると思います。
(Microsoftの実装なので、Unityとは細部が異なるかもしれませんが。)

2.またその後、変数pとメンバー変数nameをドット演算子でくっつけているのですが、これは変数pがクラス、メンバー変数nameがメソッドとなり、nameメソッドがpクラスの中で定義されているという解釈で正しいでしょうか?

class Person{
    public string name;
    ...
}

で、「Personのインスタンスは、nameというメンバを持っているからよろしく」
とコンピュータに伝えたわけです。

  • 変数pPerson型である。(=pPersonのインスタンスを格納できる)
  • Personのインスタンスはnameメンバを持つ。
  • p.nameと書くことで、pが格納するインスタンスのnameメンバにアクセスできる。

ということです。

3.showメソッドとは、どのような用途なのでしょうか?インターネットで調べても機械翻訳で書かれた説明文しか見つからず、機械翻訳の説明では読んでもわけがわかりませんでした。

オリジナルで作ったものなので、用途は自分で定義したとおりです。
showという名前も存在も人間の都合で、なにも文法でそう決まっているわけではないです。

4.最後にp.show ();がStartメソッド内で、showメソッドがPersonクラス内で書かれているのですが、これにはどんな意味があるのでしょうか?
なぜp.show ();が上で、showメソッドが下なのか。逆ではだめな理由などがあるのでしょうか? 

C#では順番はどうでもいいです。
たまたまです。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/14 13:17

    皆さん、どれもわかりやすい解答だったのですが、その中でも一番わかりやすかったのでベストアンサーとさせていただきたいと思います。

    冒頭の”読みやすさ”や”後々の拡張性のため”というのは、なるほどと思いましたし、各クラス・メソッド・変数の流れも丁寧に説明してくださり、ちゃんと理解することができました。
    プログラミングを学ぶうえで、自分は序盤でつまづくとモチベーションに関わるのでここで疑問を晴らせて本当に良かったです。
    解答してくださり、ありがとうございました。

    キャンセル

+2

1. Personクラスを作った後、StartメソッドでPerson()(コンストラクタ?)にnew演算子を付けて、Person型・変数pに代入したのは、なぜなのでしょうか?

コンストラクタ呼び出しにnewをつけるのではなくnew クラス名()で一つの文法です。参考

classによって作られたユーザー定義型は参照型となるので
変数宣言(Person p;)ではインスタンスは作られませんのでnew Person()でインスタンスを作る必要があります。

2. またその後、変数pとメンバー変数nameをドット演算子でくっつけているのですが、これは変数pがクラス、メンバー変数nameがメソッドとなり、nameメソッドがpクラスの中で定義されているという解釈で正しいでしょうか?

pはクラスではなくインスタンスです。 
よって、p.nameはインスタンスpのメンバnameへの参照であり
nameがメンバ変数なのでp.nameも変数となります。

3. showメソッドとは、どのような用途なのでしょうか?

Debug.LogについてはUnityコンソールにメッセージを記録させるメソッドとなっております。

4. 逆ではだめな理由などがあるのでしょうか?

C#に限れば、クラスの定義と呼び出しはどちらが上に書かれていても問題ありません。


もしかしたら、あなたの使っている書籍の対象読者が「C#の他にオブジェクト指向な言語を既に学んでいる」人達なのかも知れませんね

あっていない、と感じたら別の書籍を探してみるのもいいと思いますよ。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/14 13:16

    読んでて自分自身に恥ずかしくなってしまいました。
    疑問に思っていた部分は、文法だったのですね。
    その後のp.nameとshowメソッドも、普通ならあまりつまづく要素ではなかったようで、ちょっと赤面しながら読んでしまいました。
    ともあれ、概念をよく知ることができました。

    書籍ですが、他にも入門書を数冊買ってあったので、もしかしたら自分に合う内容かもしれないので今後はそちらにも目を通してみようと思います。

    本当に頭の疑念がすっきり晴れてよかったです。
    これで次に進むことができます。
    解答してくださり、ありがとうございました。

    キャンセル

+2

class Person{ ... }
と書いてるのは、クラスの定義です
このクラスを使う場合は、クラスの実体をあらかじめ作っておき、その実体に対して操作する必要があります

で、その実体というのはインスタンスと言って、 

        Person p = new Person ();

が、そのインスタンスを作るコードとなってます
インスタンス(実体)は、メモリのどこかに生成され、そのアドレスがpに代入される、と考えましょう。

これ以降、このときに生成したインスタンスは、p を通じていろいろ操作を行うことになります

3.showメソッドとは、どのような用途なのでしょうか?

public void show () {
以下のコードを読んでください。プログラムは書かれたとおりに実行されます

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/14 13:16

    まず Person p = new Person (); は、コードだったんですね。
    もっと複雑に考えてしまっていました。
    showメソッドに関しても、何かそれなりに理由がと思っていたら、そうではなかったんですね。
    安心しました。

    解答してくださり、ありがとうございました。

    キャンセル

+2

平たく言えばPerson pで居場所を保存する変数が作成され、new Person();でコードで定義されたPersonのインスタンス変数が新しく生成されます。仮に

Person p = new Person();
Person q = new Person();


と書けばpqに別々に生成されたPersonの居場所が保存されます

今回の場合pしか使っていないのに何故わざわざ新しく生成するのかと言えば、それが今後p,q,r,s,t,uとどんどん増えていく前段階の練習だからです

クラスを複数生成しない単一で使うといった使い方もあります、おそらく後々説明されるでしょう

何故Person qでPerson自体のインスタンス変数が生成されないのかといえば、プログラマー側が自由にインスタンス変数を管理するのは上級者でもバグを産みだしやすく、インスタンス変数から居場所(ポインタといいます)を作成し管理するのに多くの初心者が挫折したからです

現段階だと「居場所だけ保存するのに何故型をつけるのか」と思うかもしれませんので補足すれば、仮にDogCatクラスがあった場合、pに入っているのがPersonDogCatかわからないとなれば色々と具合が悪いからです

newが何かと言えば人間とコンパイラが誤読しないようにするための符号みたいな物なので深く考えてはいけません例えばLesson1クラス内にvoid Person()というメソッドを作成することができますが、もしこのときnewがないとPerson p = Person()が何をしたいのか解らなくなってしまいます。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/14 13:18

    インスタンス変数の管理について、上級者でもバグを産み出しやすく、初心者が挫折するという段階の説明にちょっと恐怖を覚えそうですが、今後のためにこれを読めたのは自分にとっても一つの財産となりうる情報だったので、ここで知れて良かったです。

    まだまだ学び段階ですが、まずはプログラミングを打つ段階のさらに前段階を学んでいる、本当に基礎の基礎でつまづいたってことを今回知ることができた気がします。
    ただ基礎の基礎ができないと基礎もわからないでしょうし、その上も当然さっぱりでしょうから、今回の質問で疑念が晴れたことだけでも自分は大満足です。
    解答してくださり、ありがとうございました。

    キャンセル

  • 2018/07/14 21:17

    C#は補助輪がてんこ盛りなので特にビビる必要はないです。他の言語で低レベル部分(この場合言葉で感じる高低と難易度は逆です)に触れるまで忘れていても大丈夫です。

    C#の基礎学習だとつべとかに無料動画講座とかもあるので、書籍をじっくり読む前に流し見しておくと結構掴みやすくなりますよ

    キャンセル

0

for simple and easy understand 

public class Person {

   // this is the Person class 

   public string name;  // person class has one attribute name 

   public Person () {
   // this is constructor it called whenever instance created     
    }

    public void show () {
        Debug.Log("私の名前は" + this.name); // this method print name on console
    }
}

public class Lesson1 {  // this is the main class as you know

    public static void main(string[] args){  // program run from gateway
        Person p = new Person ();   /* create instance name p having type 
                                         1. instance created
                                         2. instance call person constructor*/
        p.name = "太郎";    // assign name (now p access person attribute and set ) 
        p.show ();          // p call show method
    }
}

public class Lesson1 : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}


https://docs.unity3d.com/ScriptReference/MonoBehaviour.html
Start : whatever you write in start it execute once when program start
update : used for physics , animations etc it execute after 60fps  

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/14 13:15

    UUUUUUM…

    First. Thank you for answering my question.

    Next. I can read English very little.
    So I can't understand your teaching perfectly.
    It's my fault. I apologize to you.
    I want to saying you sorry.

    キャンセル

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

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

関連した質問

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

  • C#

    6244questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。