インスタンスの作成(=New)

タグの編集
投稿者 かな  (社会人) 投稿日時 2020/8/31 15:50:42
初心者です。
インスタンスについて質問です
ネットでは= new って書くとクラスからオブジェクト(インスタンス)が作成されるとかえてありました。
いまいちどんな時にどう使うのかよくわからないです。

ネットに転がっているコードをコピペしてなんとか理解しようとしましたが
エラーがでてさらに??って感じです。
https://turtle-engineers.com/vb-instance/
初歩でつまずいています。。
宜しくお願いします。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/8/31 17:50:16
たとえば、ツールボックスから TextBox をフォームに貼って使いますよね。

通常は Visual Studio がコードを自動生成してくれますが、これはつまり、
 Private textBox1 As TextBox
という変数に対して
 textBox1 = New TextBox()
のようにインスタンスを生成して、それをフォーム上に
 Form1.Controls.Add(textBox1)
のようにして載せて使う…という処理を意味します。

Form1 に貼った textBox1 と、Form2 に貼った textBox1 は、
機能的には全く一緒です(TextBox クラスとしての振る舞い)。

それぞれ個別に New されているため、実態(インスタンス)は別物となります。
別の TextBox として管理されているので、それぞれの別の文字列を管理できます。

「As TextBox」のところは TextBox クラスの変数定義。
「New TextBox()」のところは、TextBox クラスのインスタンスを生成している箇所。

…という説明で伝わりますかね?


一つのインスタンスを複数の変数から参照することもできます。
 Dim textBox3 As TextBox = textBox1
 textBox3.Text = "ABC"
のようにすると、textBox3 と textBox1 はいずれも同じインスタンスを差しているので、
textBox3.Text を書き換えると、textBox1 の Text も書き換わります。


上記は画面上に貼る Control についての解説ですが、
その他のクラスについても同じことが言えます。

Dim yamada As Person  'Person クラスの変数「山田」を定義 
yamada = New Person()   '「山田」変数に Person クラスのインスタンスをセット 

'上記 2 行を、下記のように 1 行で書くこともできる 
'Dim yamada As Person = New Person() 
'Dim yamada As New Person() 
'Dim yamada = New Person() 
投稿者 かな  (社会人) 投稿日時 2020/9/1 09:34:45
魔界の仮面弁士様ありがとうございます
丁寧な解説でなんとなくですが概念がわかってきたようなきがします。

Newはあってもなくても意味はかわらないのかなと思ってましたが、
付けないと式でエラーが出てしまうことがわかりました。
そしてクラスをインスタンス化するためのおまじないみたいな感じなのかなと。

といいつつ。。
実はこのクラスというものの概念も把握しきれていません。とってもふわふわしています
クラスと構造体ということばなら聞いたことあるのですが、ピンとこなくて、、
確認なのですがクラスってオブジェクトのことなのでしょうか?
クラスの調べかた教えてください。mom

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/9/1 10:59:23
例えばですよ、「名簿」クラスを作るとするじゃないですか。

その名簿の各ページには、
  姓 As String
  名 As Date
な 2 つのメンバーがあるとしましょう。


名簿を管理するにあたって、3年A組の名簿 と 3年B組の名簿は、
別々に発行したいと思います。なので別のインスタンスとして、
個別に New で実体化させます。

Dim a As New 名簿("3年A組")
a.Add("茅野""さくら")
a.Add("逢沢""博己")
a.Add("秋庭""凛")

Dim b As New 名簿("3年B組")
b.Add("浅井""雪乃")
b.Add("宮沢""保")
b.Add("阿部""トシエ")

Dim c As 名簿



変数 a と b には、それぞれ、固有の名簿インスタンスが割り当てられました。
しかし c はまだ変数が定義されただけで、実体化されていません。


クラスというのは「雛形」や「設計図」に当たります。
New でインスタンス化しなければ、操作可能な実体にはなりません。

実態化されていないうちに、c.Add でメソッドにアクセスしようとすると、
NullReferenceException のエラーになります。

c に実体を割り当てる際には、c = New 名簿("3年C組") のように、
新しい名簿を発行することもできますし、あるいは既存の実体を
c = a のようにセットして、「a と同じインスタンスを参照した状態」にもできます。


また、設計図となる名簿クラスのページ定義に、
  生年月日 As Date?
が加えられたとしたら、変数 a~c いずれの変数に対しても、
 MsgBox( a(0).生年月日 )
などのように、生年月日というメンバーが追加されることになります。



Public Class 名簿
    Inherits List(Of 頁)
    Public Property 標題 As String
    Public Sub New(標題 As String)
        Me.標題 = 標題
    End Sub
    Public Overloads Sub Add(姓 As String, 名 As StringOptional 生年月日 As Date? = Nothing)
        Add(New 頁() With {.姓 = 姓, .名 = 名, .生年月日 = 生年月日})
    End Sub
    Public Class 頁
        Public Property 姓 As String
        Public Property 名 As String
        Public Property 生年月日 As Date?
    End Class
End Class
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/9/1 15:48:53
> 確認なのですがクラスってオブジェクトのことなのでしょうか?

Yes のこともあれば、No のこともあります。文脈によりますね。


Object は、日本語では『対象物』などと訳せます。

それ自体が抽象的な言葉であり、特定の何かを表す言葉というわけではありません。
「それ」とか「モノ」と同じ程度の言葉だと思えば良いんじゃないでしょうか。

クラスのことをオブジェクトと呼ぶこともあれば、
クラスのインスタンスや変数内のデータをオブジェクトと呼ぶこともあります。
あるいは、プログラム化する前の現実世界の物体や振る舞いを指すこともあります。


たとえば、Visual Basic における As Object として使われる Object キーワードと、
クラスの解説で使われる「オブジェクト」という言葉は時として、
同じものを指していることもあれば、別なものを意味することもあります。
投稿者 かな  (社会人) 投稿日時 2020/9/1 16:10:18
クラスって自由に作れて内容を定義してあげればエラーが出ずに動くんですね
クラスは設定みたいなものなのかなとおもいました。


ちなみに私はコードがよめなくて、、確認したいです。


     Public Overloads Sub Add(姓 As String, 名 As String, Optional 生年月日 As Date? = Nothing)
       Add(New 頁() With {.姓 = 姓, .名 = 名, .生年月日 = 生年月日})

はaddという機能をNew 項 という設定に置き換えているということでしょうか?

そしてPublic Class 名簿
      Inherits List(Of 頁)←で項の設定を呼び出している?
      Public Property 標題 As String
      Public Sub New(標題 As String)
        Me.標題 = 標題
      End Sub


的違いな質問でしたらすいません。。







投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/9/1 22:59:07
> New 項 という設定
項 (こう) ではなく
頁 (ページ) ですね。


> クラスって自由に作れて内容を定義してあげればエラーが出ずに動くんですね
その「作成」「定義」を行っていくのが、プログラミングという作業です。


> クラスは設定みたいなものなのかなとおもいました。
設計図、と言えるかもしれません。

たとえば【住所録】のクラスを作るなら、そこにどんな情報を管理するのか整理し、
それは数値なのか文字列なのかを定め、項目や制限などを組み込んでいったりします。


項目は、クラスでいえばフィールド変数やプロパティに当たります。
制限というのは処理の振る舞いのことで、プロパティの入力値検査や、メソッド・関数として実装します。

【住所録】のクラスなら、こういった振る舞いを組み込むことができるでしょう。
 🔶 氏名 🔶 氏名に空欄を許可するのか? 必須入力とするのか?
         後から姓を変更することを許可するか? 許可するなら旧姓も管理するのか?
         外国人用にミドルネームやスペルも管理できるようにするか?
         
 🔶 性別 🔶 男・女だけで良いのか? 性別不明も許可するのか?

 🔶生年月日🔶 これから生まれる予定の子供の未来日付の入力を許可するか?



> Public Class 名簿
【名簿】クラスの宣言です。


>  Inherits List(Of 頁)
一冊の名簿には、複数のページ情報がありますよね。

複数のデータを管理する機能を、すべて自作するのは面倒なので、
既存の System.Collections.Generic.List(Of ) というコレクション クラスを流用して、
その機能を受け継がせています。これを、クラスの「継承(inherits)」と言います。


>  Public Property 標題 As String
名簿クラスに、「標題」という インスタンス プロパティを定義する宣言です。
標題は、文字列型(String)として宣言しています。


>  Public Sub New(標題 As String)
>   Me.標題 = 標題
>  End Sub
名簿クラスのインスタンスを生成する際には、「標題」情報を必須としたいので、
Sub New で示される「コンストラクタ(constructor)」で、標題を受け取るようにしています。

引数(パラメーター)で受け取った情報は、先ほど作った、自身の「標題」プロパティに
代入して保存します。『Me.標題 = 標題』の部分ですね。


>  Public Overloads Sub Add(姓 As String, 名 As String, Optional 生年月日 As Date? = Nothing)
>   Add(New 頁() With {.姓 = 姓, .名 = 名, .生年月日 = 生年月日})
>  End Sub
List(Of 頁) クラスは、標準で Add という処理を持ち合わせています。

List(Of 頁) クラスに標準で用意されている Add メソッドは
  b.Add( 新しい頁 )
という定義しか無かったわけですが、そこに
  b.Add( 苗字, 名前 )
  b.Add( 苗字, 名前, 生年月日 )
のような呼び出し方も行えるようにしたものがこの宣言です。


このように、パラメーター定義だけが異なる同じ名前のメソッドのことを、
メソッドの「オーバーロード(多重定義)」と言います。
『Public Overloads Sub Add(…』の "Overloads" の部分のことですね。


もし、上記の Public Overloads Sub Add~~End Sub のブロックが無かった場合は、
  Dim b As New 名簿("3年B組(平成22年度)")
  b.Add("荒井", "駿")
  b.Add("井坂", "碧")
という呼び出しの代わりに、標準の Add メソッドを用いてこのように書きます。
  Dim b As New 名簿("3年B組(平成22年度)")
  b.Add(New 名簿.頁() With { .姓 = "荒井", 名 = "駿" })
  b.Add(New 名簿.頁() With { .姓 = "井坂", 名 = "碧" })


>  Public Class 頁
>   Public Property 姓 As String
>   Public Property 名 As String
>   Public Property 生年月日 As Date?
>  End Class
先程の【名簿】クラスの宣言と同様に、
ここでは【頁】クラスの宣言が行われています。

見ての通り、3 つのメンバーが定義されており、それぞれ
  文字列型(String 型)の「姓」というプロパティ
  文字列型(String 型)の「名」というプロパティ
  Null許容日付型(Date? 型)の「生年月日」というプロパティ
という定義となっています。


> End Class
これは最初の『Public Class 名簿』の終端を意味します。

【名簿】と【頁】、2 つのクラス定義を並べて
Public Class 名簿
'    : 
End Class
Public Class 頁
'    : 
End Class

と書いても良いのですが、それが名簿の頁であることが明確となるよう、先の例では
Public Class 名簿
      :
    Public Class 頁
        :
    End Class
End Class

のような、入れ子の階層構造で定義してみました。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/9/2 00:13:21
> 【住所録】のクラスなら、こういった振る舞いを組み込むことができるでしょう。

おっと。住所録なのに、肝心の「住所」の項目を書き忘れていました…。orz

というか住所録に性別や生年月日は必須じゃないですね。うっかり。
(スマートフォンのアドレス帳/連絡先には、そうした個人情報も記録できるけれど)
投稿者 かな  (社会人) 投稿日時 2020/9/2 15:36:29
初心者にもわかりやすくコードの解説して頂いてありがとうございます。
自分ではまだ書けないですが、コードが動いてうれしかったです。

いろんなコードをコピペして動かしていくとクラスは設計図という言葉はぴったりだと理解しまた。
自分が作成したいクラスの内容を自由に作れて、かつ既存の設定継承したり、内容設計変えたり
といろいろなことができることがわかりました。


List(Of 頁) クラスは、標準で Add という処理を持ち合わせています。
>魔界の仮面弁士さんはこういうのどうやってしらべているのでしょうか?
やっぱ本とかよんで勉強とかでしょうか?

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/9/3 23:25:43
> 初心者にもわかりやすくコードの解説して頂いてありがとうございます。
お役に立てたようであれば何よりです。


以下、雑談がてらに。

>>魔界の仮面弁士さんはこういうのどうやってしらべているのでしょうか?
> やっぱ本とかよんで勉強とかでしょうか?

えぇとまぁ、情報ソースは色々ですよね。

趣味でも学問でも日本語でもプログラム言語でも日常のことでもそうですが、
一つ一つの知識について、それぞれをどうやって習得したのか、
どこで覚えたのか、何で調べたのかと問われても、答えにくい所ではあります😅


なので……具体的な話ではなく、概念的な話しかできないのですが、ざっくり言えば、
読んで、調べて、試して、失敗して、直して、繰り返して、それを人に伝えてを繰り返しているうちに、
自然と身についていくものであるのだと漠然と思っています。

自分がプログラミングを始めたのは、自分が小学校 3 年生の頃でしたが、
その当時からその作業の繰り返しでした。(まだ Visual Basic という言語は存在していません)
放課後も夏休みも、部屋にこもって独学でキーボードを打ち続ける毎日でしたが、それはさておき。


知識という物は、少しずつ積み重ねていくことで、ある日突然に
一気に理解できるようになるものであると感じています。

これは下記の記事のイメージが近いです。
https://thom.hateblo.jp/entry/2015/11/26/013559

この時、知っている事柄の総量はあまり重要では無いと思っています。
重要なのは、情報の幅あるいはそれぞれの知識の結びつき。

基礎理解度が充分に身についていれば、まったく知らない範囲の内容であっても、
類似情報や経験と照らし合わせることで、確度の高い推測が可能になりますし、
それによって得られた知見がまた、次の学習効果を生み出す結果に繋がります。


先人たちの格言や諺にも、
「好きこそ物の上手なれ」「経験に勝る知識無し」「教えることは二度学ぶこと」
などという言葉がありますよね。

ですから、
> 自分ではまだ書けないですが、コードが動いてうれしかったです。
こういう体験を積み重ねていくことが大事なんじゃないでしょうか。楽しみましょう!
投稿者 かな  (社会人) 投稿日時 2020/9/7 08:24:37
お返事遅くなってすいません。


趣味でも学問でも日本語でもプログラム言語でも日常のことでもそうですが、
一つ一つの知識について、それぞれをどうやって習得したのか、
どこで覚えたのか、何で調べたのかと問われても、答えにくい所ではあります

>いわれてみればそうですよね。変な質問に答えてくれてありがとうございます。mom
魔界の仮面弁士さんの話とリンク先よみましたがとってもためになりました。

小学校 3 年生からやっていたのはびっくりしました。
すごく続いているので
魔界の仮面弁士さんは本当にプログラミングが好きなのかなとおもいました。


先人たちの格言や諺にも、
「好きこそ物の上手なれ」「経験に勝る知識無し」「教えることは二度学ぶこと」
>この言葉すごくいいなとおもいました
手さぐり最中ですが霧が晴れるように引き続き勉強していこうと思います

ありがとうございました。