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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

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

Q&A

解決済

6回答

3015閲覧

クラスとインスタンス

MitzKuno

総合スコア12

C#

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

2グッド

2クリップ

投稿2018/07/11 17:08

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メソッドが下なのか。逆ではだめな理由などがあるのでしょうか

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

P5_USER, DeadEndShoot666👍を押しています

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

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

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

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

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

guest

回答6

0

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

あなたは神様です。
これから人間(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/12 07:09

sakura_hana

総合スコア11427

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

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

MitzKuno

2018/07/14 04:30 編集

最後に皆さんの概念を統括して体系化して物語で語ってくださり、ありがとうございました。 読み終えて「そういうことか」と掌をグーで叩けました。 今は私自身、学んでいる段階であり、今後、sakura_hanaさんのいう「何がルールで、何が自分で決めるものなのか」という点でまたいろいろな壁にぶち当たると思うのですが、まずは今の疑念が晴れて入門書の次のページを進められることに気分が高揚している次第です。 解答してくださり、ありがとうございました。
MitzKuno

2018/07/14 05:05

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

0

ベストアンサー

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

C#

1public class Lesson1 : MonoBehaviour { 2 3 // Use this for initialization 4 void Start () { 5 Debug.Log("私の名前は太郎"); 6 } 7 8 // Update is called once per frame 9 void Update () { 10 11 } 12}

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


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

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

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

C#

1class Person{ 2 ... 3}

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

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

C#

1string s = "nice text";

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

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

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

C#

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

C#

1string s = "abc";

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

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

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

C#

1class Person{ 2 public string name; 3 ... 4}

で、「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/12 00:30

編集2018/07/12 00:40
ozwk

総合スコア13521

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

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

MitzKuno

2018/07/14 04:17

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

0

平たく言えば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/12 05:17

編集2018/07/12 05:41
DeadEndShoot666

総合スコア203

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

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

MitzKuno

2018/07/14 04:18

インスタンス変数の管理について、上級者でもバグを産み出しやすく、初心者が挫折するという段階の説明にちょっと恐怖を覚えそうですが、今後のためにこれを読めたのは自分にとっても一つの財産となりうる情報だったので、ここで知れて良かったです。 まだまだ学び段階ですが、まずはプログラミングを打つ段階のさらに前段階を学んでいる、本当に基礎の基礎でつまづいたってことを今回知ることができた気がします。 ただ基礎の基礎ができないと基礎もわからないでしょうし、その上も当然さっぱりでしょうから、今回の質問で疑念が晴れたことだけでも自分は大満足です。 解答してくださり、ありがとうございました。
DeadEndShoot666

2018/07/14 12:17

C#は補助輪がてんこ盛りなので特にビビる必要はないです。他の言語で低レベル部分(この場合言葉で感じる高低と難易度は逆です)に触れるまで忘れていても大丈夫です。 C#の基礎学習だとつべとかに無料動画講座とかもあるので、書籍をじっくり読む前に流し見しておくと結構掴みやすくなりますよ
guest

0

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

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

Person p = new Person ();

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

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

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

public void show () {

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

投稿2018/07/11 23:25

y_waiwai

総合スコア87747

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

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

MitzKuno

2018/07/14 04:16

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

0

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

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

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

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

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

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

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

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

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


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

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

投稿2018/07/11 21:57

asm

総合スコア15147

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

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

MitzKuno

2018/07/14 04:16

読んでて自分自身に恥ずかしくなってしまいました。 疑問に思っていた部分は、文法だったのですね。 その後のp.nameとshowメソッドも、普通ならあまりつまづく要素ではなかったようで、ちょっと赤面しながら読んでしまいました。 ともあれ、概念をよく知ることができました。 書籍ですが、他にも入門書を数冊買ってあったので、もしかしたら自分に合う内容かもしれないので今後はそちらにも目を通してみようと思います。 本当に頭の疑念がすっきり晴れてよかったです。 これで次に進むことができます。 解答してくださり、ありがとうございました。
guest

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/11 18:23

AliHassan

総合スコア351

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

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

MitzKuno

2018/07/14 04: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.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問