2

コマンド ボタンの内容は次のとおりです。変数を作成し、それらの ID を出力しようとしているだけです (これは、基本クラスから継承されたインスタンス変数である必要があります)。

Private Sub Command1_Click()
    Dim ball1 As Ball, ball2 As Ball
    Dim cube1 As Cube, cube2 As Cube

    Set ball1 = New Ball
    Set cube1 = New Cube
    Set cube2 = New Cube
    Set ball2 = New Ball

    MsgBoxTheID (ball1)  'errors; should be 0
    MsgBoxTheID (ball2)  'errors; should be 3
    MsgBoxTheID (cube1)  'errors; should be 1
    MsgBoxTheID (cube2)  'errors; should be 2

    Call ball1.MsgBoxID  ' works; displays 0
    Call ball2.MsgBoxID  ' works; displays 3
    Call cube1.MsgBoxID  ' works; displays 1
    Call cube2.MsgBoxID  ' works; displays 2

End Sub

Model1.bas:

Global globalID As Integer

Public Sub MsgBoxTheID(theObj As BaseObj)
    ' this function is meant to accept objects of type Ball, Cube, and BaseObj
    MsgBox theObj.ID
End Sub

BaseObj クラス モジュール:

Public ID As Integer
Public isVisible As Boolean

Public Sub setVisiblity(newVis As Boolean)
    isVisible = newVis
End Sub

Public Sub MsgBoxID()
    MsgBox ID
End Sub

Private Sub Class_Initialize()
    ID = globalID
    globalID = globalID + 1
End Sub

ボール クラス モジュール:

Implements BaseObj
Private theObj As BaseObj
Public radius As Double

Private Property Let BaseObj_ID(ByVal RHS As Integer)
End Property
Private Property Get BaseObj_ID() As Integer
End Property
Private Property Let BaseObj_isVisible(ByVal RHS As Boolean)
End Property
Private Property Get BaseObj_isVisible() As Boolean
End Property

Public Sub MsgBoxID()
    Call theObj.MsgBoxID
End Sub

Private Sub BaseObj_MsgBoxID()
    Call theObj.MsgBoxID
End Sub

Public Sub BaseObj_setVisiblity(newVis As Boolean)
End Sub

Private Sub Class_Initialize()
    Set theObj = New BaseObj
End Sub

キューブ クラス モジュール:

Implements BaseObj
Private theObj As BaseObj
Public sideLength As Double

Private Property Let BaseObj_ID(ByVal RHS As Integer)
End Property
Private Property Get BaseObj_ID() As Integer
End Property
Private Property Let BaseObj_isVisible(ByVal RHS As Boolean)
End Property
Private Property Get BaseObj_isVisible() As Boolean
End Property

Public Sub MsgBoxID()
    Call theObj.MsgBoxID
End Sub

Private Sub BaseObj_MsgBoxID()
    Call theObj.MsgBoxID
End Sub

Public Sub BaseObj_setVisiblity(newVis As Boolean)
End Sub

Private Sub Class_Initialize()
    Set theObj = New BaseObj
End Sub

これについて私が気に入らない点がいくつかありますが、そのうちの 2 つは避けられない印象です: (1) C++ に比べて混乱しているという事実、および (2) Ball および Cube クラスに含まれているのは単にBaseObj タイプのオブジェクト。実際には BaseObj から何も継承していません。彼らは同じインターフェースを実装することを余儀なくされているだけです(おっと。)

さらに悪いことに、これは私が本当に修正可能であることを望んでいるものですが、パラメーターの受け渡しに関しては、基本クラスのオブジェクトを埋めることができないようです。

私は何か間違ったことをしていますか?

4

3 に答える 3

4

Visual Basic 6 は、OOP の「より純粋な」形式を学習するのに理想的な言語ではありません。VB6 は、Microsoft コンポーネント オブジェクト モデル (COM) の世界を周回するオブジェクト ベース プログラミングの非常にハイブリッド化されたバージョンを実装するように設計されており、そのインターフェイス継承指向が採用されています。VB6 は実装の継承をサポートしていないため、探している種類のポリモーフィズムを実行するのが難しくなる傾向があります。

実装の継承の問題を「回避する」(一種の) VB6 時代から思い出すいくつかのトリックがあります。特に、サブクラスを基本クラスのオブジェクトに置き換える場合にそうです。私が覚えている 1 つのトリックは、戻り値の型として "Me" への参照を返す基本インターフェイスの型のプロパティ プロシージャを宣言することです。これは、ランタイムを「トリック」して、目的のインターフェイスへの変換を提供します。VB6 のデザイン ダイアログの 1 つで「手続き番号」を -4 に設定して、プロパティを「デフォルト」プロパティにするもう 1 つの手品があります。

ポイント?本当に従来のオブジェクト指向プログラミングに取り掛かりたい場合は、必要がなければ VB6 で学習しようとしないでください。(少なくとも) VB.NET、C#、または Java に移行します。私は VB6 が嫌いだとは言いませんが、これらの愚かな詳細が長い間法案を支払っていたことを知っていますが、それ自体の小さな特異性を OOP の優れた基本的な理解に変換するのは難しいことです。

幸運を!

于 2012-07-17T04:07:53.833 に答える
3

エラーを修正する方法はわかりましたが、「理由」を提供します。

VB6 (および VB5 など) では、メソッド/関数/サブルーチン/ステートメントを呼び出すための構文が 2 つあります。最初はこれです:

MySubName arg1, arg2, arg3, arg4

Blech、これは私の C と Java からの偏見であることはわかっていますが、引数リストを括弧で囲むのが好きです。その構文は次のとおりです。

Call MySubName(arg1, arg2, arg3, arg4)

したがって、これら2つは同等です。

あなたが遭遇したのは、コールの影響ではありません。あなたが遭遇したのは、非 Call バージョンの不要な括弧の影響です。括弧は、その中のステートメント/引数をステートメントの残りの部分の前に評価するように強制します (演算の数学的な順序を考えてください)。

したがって、この:

SomeSub (arg1)

このようなものです:

temp = (arg1) 
SomeSub temp

さらに、VB6 のオブジェクトは「デフォルト プロパティ」を持つことができます。これにより、次のようなコードを記述できます。

Dim name as String
name = txtName

textbox オブジェクト参照を name に割り当てる代わりに、.Text のデフォルト プロパティが使用され、結果は次のようになります。

Dim name as String
name = txtName.Text

したがって、評価しようSomeSub (arg1)とすると、オブジェクトのデフォルト プロパティを見つけて実行し、その値を に渡そうとすると思いますSomeSub

于 2012-07-17T12:15:35.523 に答える
0

まあ、私はそれを理解しました。

MsgBoxTheID (ball1)  'errors; should be 0
MsgBoxTheID (ball2)  'errors; should be 3
MsgBoxTheID (cube1)  'errors; should be 1
MsgBoxTheID (cube2)  'errors; should be 2

...に変更する必要があります...

Call MsgBoxTheID (ball1)  'errors; should be 0
Call MsgBoxTheID (ball2)  'errors; should be 3
Call MsgBoxTheID (cube1)  'errors; should be 1
Call MsgBoxTheID (cube2)  'errors; should be 2

...戻り値の型がありませんが、変数を宣言しなくても戻り値を破棄するために使用できるものだMsgBoxTheIDといつも思っていたので、これは奇妙です。Call

dim unneededVar as Integer
unneededVar = FunctionNameThatReturnsAnInteger()

しかし、そうではないと思います。だから... このサンプルプログラムを機能させるには、ステートメントが何をしているのかを正確に読む必要がありますが、Call今では間違いなく機能しています。(実装しているクラスのメソッドにも追加BaseObj_ID = theObj.IDする必要がありました。)Property Get BaseObj_ID() As IntegerBaseObj

于 2012-07-17T10:06:20.370 に答える