Visual Basic 中学校 掲示板
投稿内容
タグのない投稿を抽出
統計
RSS
Visual Basic 中学校
>
投稿一覧
>
継承とプロパティについて教えてください
タグの編集...
投稿者
tamuLA
 (社会人)   投稿日時
2022/5/9 22:13:09
下記のようなコードで
Public Class 社員
Public Shared Property ID As Integer
End Class
Public Class AAA
Inherits 社員
End Class
Public Class BBB
Inherits 社員
End Class
・
・
・
AAA.IDに値を代入するとBBB.IDにも同じ値が代入されてしまいます。
値を別々に保持したいのですが、この場合どのようなコードに修正すればよろしいでしょうか。
色々試したのですが全てダメでした。
※継承がイマイチ解っておらず、的外れなコードになっているかもしれません。申し訳ございません。
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2022/5/9 23:05:20
> AAA.IDに値を代入するとBBB.IDにも同じ値が代入されてしまいます。
Shared Property ID はシャドウイングされていないため、
AAA.ID や BBB.ID へのアクセスは、単に 社員.ID へのアクセスと同義です。
シャドウイングすれば別物となります。
Public
Class
AAA
Inherits
社員
Public
Shared
Shadows
Property
ID
As
Integer
End
Class
実装を変更する方法としては、シャドウイングのほかにオーバーライドがありますが、
Shared はオーバーライドできない仕様です。(オーバーライドできるのはインスタンスメンバーのみ)
> 値を別々に保持したいのですが、この場合どのようなコードに修正すればよろしいでしょうか。
別々の値を保持したいのであれば、Shared ではなくインスタンスメンバーにすべきです。
インスタンスメンバーであれば、個別の値を持てますし、必要に応じてオーバーライドもできます。
複数のインスタンスが不要なら、Singleton な実装にしておけばよいわけで。
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2022/5/9 23:08:16
無理矢理ですが、
Public Shared Property ID() As Integer
をベースクラスに用意したまま、継承先で異なる ID を保持させてみる。
Module
Module1
Public
MustInherit
Class
社員(
Of
T)
Private
Shared
ReadOnly
InternalIDs
As
New
Dictionary(
Of
Type,
Integer
)()
Public
Shared
Property
ID()
As
Integer
Get
Dim
currentID
As
Integer
InternalIDs.TryGetValue(
GetType
(T), currentID)
Return
currentID
End
Get
Set
(
ByVal
newID
As
Integer
)
InternalIDs(
GetType
(T)) = newID
End
Set
End
Property
End
Class
Public
Class
AAA
Inherits
社員(
Of
AAA)
End
Class
Public
Class
BBB
Inherits
社員(
Of
BBB)
End
Class
Sub
Main()
AAA.ID = 123
BBB.ID = 456
MsgBox(AAA.ID)
MsgBox(BBB.ID)
End
Sub
End
Module
投稿者
(削除されました)
 ()   投稿日時
2022/5/9 23:08:17
(削除されました)
投稿者
(削除されました)
 ()   投稿日時
2022/5/10 12:07:46
(削除されました)
投稿者
tamuLA
 (社会人)   投稿日時
2022/5/10 12:15:32
仮面弁士さん、昔からお世話になりっぱなしで直接ご回答頂いたことに大変大変恐縮です。
>別々の値を保持したいのであれば、Shared ではなくインスタンスメンバーにすべきです。
となると、newで動的にインスタンス化して管理してくのが(浅い理解でなんか表現が変かも)
設計として自然な感じでしょうか。
あとシャドウイングというものを全く知りませんでした。ありがとうございます。
私がスレ立てしたようなコードの形でシャドウイングで書くと、
Public
Class
AAA
Inherits
社員
Public
Shared
Shadows
Property
ID
As
Integer
End
Class
Public
Class
BBB
Inherits
社員
Public
Shared
Shadows
Property
ID
As
Integer
End
Class
・
・
・
とPublic Shared Shadows Property ID As Integer を書きまくらないといけない感じで
設計としては不自然になるという感じでしょうか。
力不足でコードのほうまだ追えていないのですが、こちらもじっくり取り組んでみたいと思います。
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2022/5/10 12:57:14
まず Shared は、その名の通り「共有」です。個別の値を持つには適しません。
また Shared は、継承先でオーバーロードができないので、
・既存の Shared メンバーをそのまま受け継ぐ(動作は変更できない)
・新しい Shared メンバーを追加する(継承元には影響しない)
・既存の Shared メンバーを見えなくし、同名のメンバーでシャドウイングする。
の 3 パターンとなります。
VB の仕組み上、Interface に Shared なメンバーを追加することもできません。
(C# の場合は 8.0 以降で、インターフェイスへの共有メンバーの追加が許可されましたが)
> newで動的にインスタンス化して管理してくの
シングルトンにしてプロパティで単一のインスタンスを返すようにしたり、
ファクトリーメソッドを作りこんだりして、New することを
呼び出し側に意識させない設計にしては如何ですか?
たとえば
Dim s1 As String = My.Computer.Name
という処理は、
Dim c As New My.MyComputer()
Dim s2 As String = c.Name
とも書けますが、利用者側は通常、New せずに使うことできますよね。
> 設計としては不自然になるという感じでしょうか。
コード云々以前に、クラス設計が不自然というか、そもそもの『意図』が不明瞭ですね。
社員クラスは MustInherit なわけでもないのに、
それを継承した AAA 側は、何も追加改修されていませんから…。
投稿者
shu
 (社会人)   投稿日時
2022/5/10 16:34:28
IDが社員を特定するものであれば
Sharedで定義すること自体がダメです。
AAA, BBBがどのようなものを想定しているか分かりませんが
AAA:佐藤さん
BBB:木村さん
のように想定しているのであれば継承をせず
社員クラスに情報を追加して
佐藤さん用の変数、木村さん用の変数を社員クラスをnewで作成するのが
通常です。
AAA:営業部
BBB:技術部
というような想定であれば
共通の情報は社員クラスに配置し
営業部固有の情報はAAAクラスに
技術部固有の情報はBBBクラスに配置するとよいです。
この想定でも社員毎にAAAまたはBBBBに対しnewをして情報を保存するのは変わりません。
投稿者
(削除されました)
 ()   投稿日時
2022/5/11 23:47:16
(削除されました)
投稿者
(削除されました)
 ()   投稿日時
2022/5/12 00:13:54
(削除されました)
投稿者
tamuLA
 (社会人)   投稿日時
2022/5/12 00:17:49
仮面弁士様、shu様、丁寧にご回答頂いて重ねて恐縮です。
大体問題が解ってきました。
>そもそもの『意図』
ここに尽きると思うのですが、
最初、グローバル変数が並んでたのがどんどん増えてしまい
クラスにしたら解りやすいかなと思い下記のようなコードになりました。
(Sharedはアクセス修飾子を考えないようにしたいという安易な考えで入れてました)
Public
Class
AAA
Public
Shared
Property
ID
As
Integer
Public
Shared
Property
Name
As
String
End
Class
そのままOOPを解ってない状態でコードが膨れていき、
数年開発を続けてたらこういう形でものすごい量に増長してしまいました。
Public
Class
AAA
Public
Shared
Property
ID
As
Integer
Public
Shared
Property
Name
As
String
Public
Shared
Property
Score
As
Integer
・
・
・
End
Class
Public
Class
BBB(内容は同上)
Public
Class
CCC(内容は同上)
Public
Class
DDD(内容は同上)
Public
Class
EEE(内容は同上)
・
・
・
これを1発でなにか短縮できないかと考えあまり使ったことない継承で
コードが激減するのではと考えた結果、
スレ立てしたようなコードにしたら良いのかな?と思ってハマってたという顛末です。
Public
Class
社員
Public
Shared
Property
ID
As
Integer
Public
Shared
Property
Name
As
String
Public
Shared
Property
Score
As
Integer
End
Class
Public
Class
AAA
Inherits
社員
End
Class
Public
Class
BBB
Inherits
社員
End
Class
・
・
・
ご回答に関して正直まだ解っていないところが多いのですが、
ここ2日ぐらい集中的に勉強しておりまして、ご回答の記載が6割ぐらい解るようになりました。
解決方法は最初に提示されたこちら
>別々の値を保持したいのであれば、Shared ではなくインスタンスメンバーにすべきです。
につきるということが段々解ってきており、おそらくOOPに合うような設計とコードに
変えることが解決であるようです。
本日もご回答を繰り返し読み返して勉強しております。
このような感じの質問にお時間を使っていただきすみません。感謝しております。m(__)m
引き続き勉強する所存です。