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

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

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

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

3回答

12749閲覧

vbaでのクラス継承時の定数について

K.T_build

総合スコア29

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

2クリップ

投稿2017/08/17 04:00

編集2017/08/17 06:14

vbaでの継承について、質問をさせて頂きます。
javaのようにスーパークラスにメンバ変数を設定し、それのアクセスをしたいのですが毎回インターフェースを設定する必要があるのでしょうか?

###理想

vba

1'スーパークラス:absClass.cls 2Option Explicit 3 4'プロパティ 5Private WS As Worksheet 6Private wsName As String 7Private startCol As Integer 8Private startRow As Integer 9 10Public Sub calc() 11End Sub

vba

1'サブクラス:centerToMonth.cls 2Option Explicit 3Implements absClass 4 5Private Sub Class_Initialize() 6 '初期値宣言 7 wsName = "営業所別_月間" 8 startCol = 3 9 startRow = 6 10 Set WS = ActiveWorkbook.Worksheets(wsName) 11End Sub 12 13Private Sub absClass_calc() 14 '計算処理 15End Sub 16 17Private sub hoge() 18End Sub

###現実?

vba

1 2'スーパークラス:absClass.cls 3Option Explicit 4 5'プロパティ 6'Public WS As Worksheet 7'Public wsName As String 8'Public startCol As Integer 9'Public startRow As Integer 10'Public colLen As Integer 11 12'' プロパティのインターフェイスを用意する。 13Public Property Get WS() As Worksheet 14End Property 15Public Property Get wsName() As String 16End Property 17Public Property Get startCol() As Integer 18End Property 19Public Property Get startRow() As Integer 20End Property 21 22Public Sub calc() 23End Sub 24

vba

1'サブクラス:centerToMonth.cls 2 3Option Explicit 4Implements absClass 5 6'プロパティ 7'【質問点】何故サブクラスで宣言するのでしょうか? 8Private WS As Worksheet 9Private wsName As String 10Private startCol As Integer 11Private startRow As Integer 12 13'メンバー設定 14Public Property Get absClass_WS() As Worksheet 15 Set absClass_WS = WS 16End Property 17Private Property Get absClass_wsName() As String 18 'absClass_wsName = wsName 19 absClass_wsName = "営業所別_月間" 20End Property 21Private Property Get absClass_startCol() As Integer 22 absClass_startCol = startCol 23End Property 24Private Property Get absClass_startRow() As Integer 25 absClass_startRow = startRow 26End Property 27 28 29Private Sub Class_Initialize() 30 '【質問点】定数を設定する場合はInitializeでするのが一般的でしょうか? 31 ' それともgetterでするのがよいのでしょうか? 32 '初期値宣言 33 wsName = "営業所別_月間" 34 startCol = 3 35 startRow = 6 36 Set WS = ActiveWorkbook.Worksheets(wsName) 37End Sub 38 39Private Sub absClass_calc() 40 '計算処理 41End Sub 42 43Private sub hoge() 44End Sub

http://teratail.com/questions/88452[前回の質問の続きです。]


【質問点まとめ】
0. メンバ変数の宣言は何故サブクラスで行うのでしょうか?
0. メンバ変数を宣言するのに、毎回インターフェース(setter, getter)を設定する必要があるのでしょうか?

また、よろしければ皆さんならばこうしているという例文などをいただけると非常に助かります。

オブジェクト指向も学習中で突飛な質問かもしれませんがよろしくお願い致します。


###【(追記)やりたいこと】
###スーパークラス
0. 単月系シート処理用
0. 年間系シート処理用

###サブクラス
0. 事業所一覧_月間シート処理(単月系シート処理用を継承)
0. 事業所別営業一覧_月間シート処理(単月系シート処理用を継承)
0. 営業別得意先一覧_月間シート処理(単月系シート処理用を継承)
0. 営業別外注一覧_月間シート処理(単月系シート処理用を継承)
0. 事業所一覧_年間シート処理(年間系シート処理用を継承)
0. 事業所別営業一覧_年間シート処理(年間系シート処理用を継承)
0. 営業別得意先一覧_年間シート処理(年間系シート処理用を継承)
0. 営業別外注一覧_年間シート処理(年間系シート処理用を継承)

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

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

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

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

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

guest

回答3

0

ベストアンサー

こんにちは。

そもそも、スーパークラスとサブクラスの関係にするということは、複数のサブクラスを作りたいということだと思いますが、合っていますか?
複数のサブクラスを作成する必要がなければ、単純にクラスだけ作れば良いので。

1.メンバ変数の宣言は何故サブクラスで行うのでしょうか?

⇒継承しているスーパークラスはあくまで抽象クラスとして実体は持っていないから。

2.メンバ変数を宣言するのに、毎回インターフェース(setter, getter)を設定する必要があるのでしょうか?

⇒サブクラスとして固有のものなら不要ですけど、インターフェースとして共通化したいなら必要です。

投稿2017/08/17 05:25

sazi

総合スコア25138

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

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

K.T_build

2017/08/17 06:08

回答ありがとうございます。 >そもそも、スーパークラスとサブクラスの関係にするということは、複数のサブクラスを作りたいということだと思いますが、合っていますか? >複数のサブクラスを作成する必要がなければ、単純にクラスだけ作れば良いので ⇒はい、その通りです。  詳しくは先ほど、質問文にやりたいことを追記しましたので見ていただければ助かります。 >⇒サブクラスとして固有のものなら不要ですけど、インターフェースとして共通化したいなら必要です。 各クラス、必須のものとして共通化させたいんですが、初期値を入れれば以降変更することの無い「定数」のような扱いをしたいため、毎回setter,getterを設定するしかないのか? といったもやもやしたものを感じて質問させてもらいました。
sazi

2017/08/17 06:29

そうゆうことなら、共通のクラスを作って各個別のクラスはそのインスタンスを生成して利用するというルールでやった方が、保守性は良さそうですけどね。
K.T_build

2017/08/17 06:37 編集

>共通のクラスを作って各個別のクラスはそのインスタンスを生成して利用する えーと、よくわかっていないんですがそれは継承とはまた違うのでしょうか? それとも共通クラスだけ作って、必要な分だけ new していく形にするということでしょうか? hoge1 = new 共通クラス(); hoge2 = new 共通クラス(); hoge3 = new 共通クラス(); etc
sazi

2017/08/17 10:10

現状で言うサブクラスのコンストラクタで共通クラスのインスタンスを生成して、そのクラス内で利用するようなことです。
K.T_build

2017/08/17 10:28 編集

BeatStarさんも言われていたコンポジションのことであってますでしょうか?   ※http://promamo.com/?p=4291 簡単に書いてみましたがこんなイメージでしょうか? /*---------------------------------------------- ■共通クラス(SuperClass) private name As String private count As Integer /*---------------------------------------------- ■サブクラス1(sub1) private super As SuperClass private const startRow As Integer = 1 private const startCol As Integer = 1 private sub Class_Initialize()   super = new SuperClass();   super.name = "hoge";   super.count = 1; end sub private function getName()   getName = super.name end function /*---------------------------------------------- ■サブクラス2(sub2) 以下略
sazi

2017/08/17 10:58

そうですね。 共通でgetter/setterを作らないなら、publicで宣言しないと駄目ですけど、そんな感じです。 これであれば、定数も共通クラスに定義すればいいですし。(getterは必要ですけど)
guest

0

私は趣味でC++でやっています。なので的外れなこと言う可能性がありますが。

変数だけのクラスはインターフェースとは言わないようです。

インターフェースは「こういうメソッドを持っている」っていう定義。

単なる定義です。外部に公開するためのもの。質問者さんは外部の人に「私の家はここにあり、こういう宝石や金になるものを持っています」なんて公開しますか?

「VB インターフェース メリット」で検索すると、

連載! とことん VB: 第 15 回 インターフェイスの使いどころ

がヒットしました。

インターフェースを定義して何が楽しいか。

それは (そのインターフェースを継承していれば ) どのクラスのオブジェクトだろうが そのメソッドを使うことが出来るっていうこと。

例えば ITest っていうインターフェースを継承すれば

Dim test As ITest test = New Test1("Hello")

ってやると、

test は ITestで定義されているやつは"必ず持っている"のでどのクラスのオブジェクトかを気にせずに使える。

( 必ず実装しないといけないってことは、実装完了していれば 要件を満たしているってことで、持っているってことにもなるため。 )

で、privateな変数は使用者からすればどーでもいい。

必要なのは、そのクラスで何ができるかと、どういうメソッドを持っているかだけ。( 例外がある言語だと例外の有無や例外の種類も。 )

なので インターフェースは 変数を定義できない。

もしできるとしたら、インターフェースじゃなくて 単なるクラス ( 親クラス。 )です。

ということで変数は基本的には 実装クラスで定義。

ですが、単なるクラス ( 名称がわからない... ) として定義し、それを継承するなら フィールドとして定義できます。

その場合は言語によるのかもしれませんが、protected にするか、private フィールド & get/set になると思います。

投稿2017/08/17 05:21

BeatStar

総合スコア4958

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

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

K.T_build

2017/08/17 05:44

インターフェース = 基礎的な機能の枠組という認識であってますでしょうか?   ※Animal インターフェースなら、「走る機能」、「吼える機能」、「食べる機能」など
K.T_build

2017/08/17 05:49

理想としては、インターフェース ⇒ 親クラス ⇒ 子クラス の流れができればベストかと考えています。 ただ、親クラスの継承はVBAではできないようです、、、   http://thom.hateblo.jp/entry/2015/02/09/015135
BeatStar

2017/08/17 09:27

私は趣味でやっているので、詳しくはわかりませんが、 インターフェース = 基本機能の枠組み っていう解釈でいいと思います。 少なくともこういうメソッドは持っているから...っていう。 親クラスの継承はできない ( on VBA ) ... 初めて知りました。 一応、ちょこちょこ VBAもやったりしますが、ほとんど ( 今のところ全部か。 ) C言語みたいに関数としてやっているので... それなら 親 -> 子 のときはコンポジション ( 包含 ) ではどうでしょうか。 コンストラクタにあたるやつ ( init か? ) で New で生成して、メンバとして保持するやつ。 よくデザインパターンで使われている技法です。 それで、 Interface -> 親 Interface -> 子 で 子は 親をコンポジションするとか。 ただあまり継承を多用して深くなりすぎると 追いにくいから出来ないってことでは? ( 言語的であっても。 それでサポートから除外とか。 )
guest

0

A1.
VBA のスーパークラスには、メンバ関数以外記述できない仕組みなので、変数宣言は記載できないからです。

A2.
提示された、理想の absClass.cls で書かれている「プロパティ」とコメントされているものは、absClass.cls 内でのみ参照可能な「ローカル変数」に該当します。
各クラスで public で変数を宣言すれば「プロパティもどき」はできますが、スーパークラスを用意する意味がなくなってしまいますね。

参考となりそうなホームページを2件示しておきます。
後者はなかなか奥深く、かつ興味深い話でした。

変数の適用範囲
オブジェクト指向と10年戦ってわかったこと

投稿2017/08/17 05:09

tukuroku

総合スコア234

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

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

K.T_build

2017/08/17 05:15

ありがとうございます。 早速頂いた情報を読ませていただきます。 ひとまずご返信まで
K.T_build

2017/08/17 05:39

頂いた情報を読ませていただきました。(2つ目は難しく消化しきれているか自信がないですが...) A1. VBAではやはり変数の継承は出来ないのですね。残念です。 A2. 理想のほうは親クラスから子クラスへの継承をイメージしました。けれどVBAでは、インターフェースしか継承できないようですね。 [リンク](http://thom.hateblo.jp/entry/2015/02/09/015135)   ※リンク設定がわからないw
K.T_build

2017/08/17 05:49 編集

定数を設定するには、サブクラスに private const hoge As ~ みたいな形だけ宣言して、スーパークラス(インターフェース)には何も宣言しない形が一般的になるのでしょうか?
tukuroku

2017/08/17 07:26 編集

> 定数を設定するには、サブクラスに private const hoge As ~ みたいな形だけ宣言して、スーパークラス(インターフェース)には何も宣言しない形が一般的になるのでしょうか? 以下のように、読み取り専用のプロパティのインターフェイスが必要になりそうですね。 (1) スーパークラスに、public property get hoge ... を宣言。 (2) サブクラスで private const hoge ... の定数を宣言。 (3) サブクラスで public property get hoge ... プロパティの実装。 ※コメントは、md の書式が効かないみたいです。
K.T_build

2017/08/17 09:23

なるほど、有難う御座います。 setterは定義せずにサブクラスでconstするんですね、試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問