Home All Groups Group Topic Archive Search About

Problem implementing an interface

Author
17 Oct 2005 11:08 AM
Robert
Hello folks,

Suppose I have two classes in an ActiveX-Control project. Both are
"Private".

One is an abstract class and contains only the following declaration:

'------------------------------------------------

Public Property Get OwnCrvID() As Long
End Property

'------------------------------------------------

The other class looks like this:

'------------------------------------------------

Implements clsMyAbstractClass

Private lngCrvID as Long

Public Property Get OwnCrvID() As Long
   OwnCrvID = lngCrvID
End Property

'------------------------------------------------

When I try to compile, I always get the error "Object module needs to
implement 'OwnCrvID' for interface 'clsMyAbstractClass'"

Why's that? Do interfaces only work for public classes? That doesn't seem to
be the problem, because I tried changing the classes to "Public not
creatable", to no avail. Have I overlooked something?

Thanks for any hints!

Robert

Author
17 Oct 2005 11:22 AM
Mike D Sutton
> Suppose I have two classes in an ActiveX-Control project. Both are
> "Private".
>
> One is an abstract class and contains only the following declaration:
<code snipped>
> When I try to compile, I always get the error "Object module needs to
> implement 'OwnCrvID' for interface 'clsMyAbstractClass'"
>
> Why's that? Do interfaces only work for public classes? That doesn't seem
> to
> be the problem, because I tried changing the classes to "Public not
> creatable", to no avail. Have I overlooked something?

The method signature should be:

'***
Private Property Get clsMyAbstractClass_OwnCrvID() As Long
'***

If you select "clsMyAbstractClass" under the object dropdown at the top of
the code window, the procedure dropdown will allow you to select the methods
it needs to implement and will add the method stubs for you when selected.
You will also need to type-cast the object to it's interface in order to
access this property, I find a simple casting function works well for this:

'***
Private Function MyAbstractClassCast(ByVal inMyAbstractClass As
clsMyAbstractClass) As clsMyAbstractClass
    Set MyAbstractClassCast = inMyAbstractClass
End Function

....

Dim X As clsSomeClassThatImplementsInterface

Set X = New clsSomeClassThatImplementsInterface
Call MsgBox(MyAbstractClassCast(X).OwnCrvID)
Set X = Nothing
'***

Hope this helps,

    Mike


- Microsoft Visual Basic MVP -
E-Mail: ED***@mvps.org
WWW: Http://EDais.mvps.org/
Author
17 Oct 2005 11:46 AM
Robert
Gosh...my memory seems to have gone on strike.
Thanks for getting me back on track!

Robert

Show quoteHide quote
"Mike D Sutton" <ED***@mvps.org> wrote in message
news:ezHmO0w0FHA.3300@TK2MSFTNGP15.phx.gbl...
> > Suppose I have two classes in an ActiveX-Control project. Both are
> > "Private".
> >
> > One is an abstract class and contains only the following declaration:
> <code snipped>
> > When I try to compile, I always get the error "Object module needs to
> > implement 'OwnCrvID' for interface 'clsMyAbstractClass'"
> >
> > Why's that? Do interfaces only work for public classes? That doesn't
seem
> > to
> > be the problem, because I tried changing the classes to "Public not
> > creatable", to no avail. Have I overlooked something?
>
> The method signature should be:
>
> '***
> Private Property Get clsMyAbstractClass_OwnCrvID() As Long
> '***
>
> If you select "clsMyAbstractClass" under the object dropdown at the top of
> the code window, the procedure dropdown will allow you to select the
methods
> it needs to implement and will add the method stubs for you when selected.
> You will also need to type-cast the object to it's interface in order to
> access this property, I find a simple casting function works well for
this:
>
> '***
> Private Function MyAbstractClassCast(ByVal inMyAbstractClass As
> clsMyAbstractClass) As clsMyAbstractClass
>     Set MyAbstractClassCast = inMyAbstractClass
> End Function
>
> ...
>
> Dim X As clsSomeClassThatImplementsInterface
>
> Set X = New clsSomeClassThatImplementsInterface
> Call MsgBox(MyAbstractClassCast(X).OwnCrvID)
> Set X = Nothing
> '***
>
> Hope this helps,
>
>     Mike
>
>
>  - Microsoft Visual Basic MVP -
> E-Mail: ED***@mvps.org
> WWW: Http://EDais.mvps.org/
>
>
Author
17 Oct 2005 11:55 AM
Martin de Jong
Neah, you just looking into the future:)

ML

Show quoteHide quote
"Robert" <no***@nowhere.com> schreef in bericht
news:O$SdyBx0FHA.2792@tk2msftngp13.phx.gbl...
> Gosh...my memory seems to have gone on strike.
> Thanks for getting me back on track!
>
> Robert
>
> "Mike D Sutton" <ED***@mvps.org> wrote in message
> news:ezHmO0w0FHA.3300@TK2MSFTNGP15.phx.gbl...
> > > Suppose I have two classes in an ActiveX-Control project. Both are
> > > "Private".
> > >
> > > One is an abstract class and contains only the following declaration:
> > <code snipped>
> > > When I try to compile, I always get the error "Object module needs to
> > > implement 'OwnCrvID' for interface 'clsMyAbstractClass'"
> > >
> > > Why's that? Do interfaces only work for public classes? That doesn't
> seem
> > > to
> > > be the problem, because I tried changing the classes to "Public not
> > > creatable", to no avail. Have I overlooked something?
> >
> > The method signature should be:
> >
> > '***
> > Private Property Get clsMyAbstractClass_OwnCrvID() As Long
> > '***
> >
> > If you select "clsMyAbstractClass" under the object dropdown at the top
of
> > the code window, the procedure dropdown will allow you to select the
> methods
> > it needs to implement and will add the method stubs for you when
selected.
> > You will also need to type-cast the object to it's interface in order to
> > access this property, I find a simple casting function works well for
> this:
> >
> > '***
> > Private Function MyAbstractClassCast(ByVal inMyAbstractClass As
> > clsMyAbstractClass) As clsMyAbstractClass
> >     Set MyAbstractClassCast = inMyAbstractClass
> > End Function
> >
> > ...
> >
> > Dim X As clsSomeClassThatImplementsInterface
> >
> > Set X = New clsSomeClassThatImplementsInterface
> > Call MsgBox(MyAbstractClassCast(X).OwnCrvID)
> > Set X = Nothing
> > '***
> >
> > Hope this helps,
> >
> >     Mike
> >
> >
> >  - Microsoft Visual Basic MVP -
> > E-Mail: ED***@mvps.org
> > WWW: Http://EDais.mvps.org/
> >
> >
>
>
Author
17 Oct 2005 12:31 PM
Robert
Uh, I'm afraid of the future...
so far, I've tried to use interfaces three or four times (in a complex
environment). Every time, I sooner or later found some limitation that made
interfaces completely unuseable in my specific case. So I'm just wondering
what limitation will turn up this time...
Don't talk about the future to me! ;-)

Robert

Show quoteHide quote
"Martin de Jong" <ML@community.nospam> wrote in message
news:%23hvtoHx0FHA.2924@TK2MSFTNGP15.phx.gbl...
> Neah, you just looking into the future:)
>
> ML
>
> "Robert" <no***@nowhere.com> schreef in bericht
> news:O$SdyBx0FHA.2792@tk2msftngp13.phx.gbl...
> > Gosh...my memory seems to have gone on strike.
> > Thanks for getting me back on track!
> >
> > Robert
> >
> > "Mike D Sutton" <ED***@mvps.org> wrote in message
> > news:ezHmO0w0FHA.3300@TK2MSFTNGP15.phx.gbl...
> > > > Suppose I have two classes in an ActiveX-Control project. Both are
> > > > "Private".
> > > >
> > > > One is an abstract class and contains only the following
declaration:
> > > <code snipped>
> > > > When I try to compile, I always get the error "Object module needs
to
> > > > implement 'OwnCrvID' for interface 'clsMyAbstractClass'"
> > > >
> > > > Why's that? Do interfaces only work for public classes? That doesn't
> > seem
> > > > to
> > > > be the problem, because I tried changing the classes to "Public not
> > > > creatable", to no avail. Have I overlooked something?
> > >
> > > The method signature should be:
> > >
> > > '***
> > > Private Property Get clsMyAbstractClass_OwnCrvID() As Long
> > > '***
> > >
> > > If you select "clsMyAbstractClass" under the object dropdown at the
top
> of
> > > the code window, the procedure dropdown will allow you to select the
> > methods
> > > it needs to implement and will add the method stubs for you when
> selected.
> > > You will also need to type-cast the object to it's interface in order
to
> > > access this property, I find a simple casting function works well for
> > this:
> > >
> > > '***
> > > Private Function MyAbstractClassCast(ByVal inMyAbstractClass As
> > > clsMyAbstractClass) As clsMyAbstractClass
> > >     Set MyAbstractClassCast = inMyAbstractClass
> > > End Function
> > >
> > > ...
> > >
> > > Dim X As clsSomeClassThatImplementsInterface
> > >
> > > Set X = New clsSomeClassThatImplementsInterface
> > > Call MsgBox(MyAbstractClassCast(X).OwnCrvID)
> > > Set X = Nothing
> > > '***
> > >
> > > Hope this helps,
> > >
> > >     Mike
> > >
> > >
> > >  - Microsoft Visual Basic MVP -
> > > E-Mail: ED***@mvps.org
> > > WWW: Http://EDais.mvps.org/
> > >
> > >
> >
> >
>
>
Author
17 Oct 2005 12:39 PM
Phill. W
Show quote Hide quote
"Mike D Sutton" <ED***@mvps.org> wrote in message
news:ezHmO0w0FHA.3300@TK2MSFTNGP15.phx.gbl...
> You will also need to type-cast the object to it's interface in order
> to access this property, I find a simple casting function works well
> for this:
>
> Private Function MyAbstractClassCast( _
>   ByVal inMyAbstractClass As clsMyAbstractClass _
> ) As clsMyAbstractClass
>     Set MyAbstractClassCast = inMyAbstractClass
> End Function
>
> Dim X As clsSomeClassThatImplementsInterface
> Set X = New clsSomeClassThatImplementsInterface
> Call MsgBox(MyAbstractClassCast(X).OwnCrvID)
> Set X = Nothing

Am /I/ missing something or does the following not work just
as well, and with rather less code?

' Create an AbstractClass-shaped variable ...
Dim x As clsMyAbstractClass

' ... into which a class that implements it will "fit" ...
Set x = New clsSomeClassThatImplementsInterface

' ... and use it "as" the Interface.
Call MsgBox( x.OwnCrvID )

Regards,
    Phill  W.
Author
17 Oct 2005 12:55 PM
Robert
Not quite.
Set x = New clsSomeClassThatImplementsInterface causes a type mismatch,
since x is declared as a different object type.
However, you can do it like this:

' Create an AbstractClass-shaped variable ...
' GLOBAL SCOPE
Dim x As clsMyAbstractClass

' [...]

' FUNCTION SCOPE (SOME INIT FUNCTION)
Dim tempObj as clsSomeClassThatImplementsInterface

' ... into which a class that implements it will "fit" ...
Set tempObj= New clsSomeClassThatImplementsInterface
Set x = tempObj

' Now x can directly access the interface functions - but only those

' ... and use it "as" the Interface.
Call MsgBox( x.OwnCrvID )

For me, this is the solution of choice, since I don't have any public
functions other than those defined in the abstract class. If you need to
access both the interface functions and non-interface public functions,
using two globally held references to the same class (one declared as
"clsMyAbstractClass", the other as "clsSomeClassThatImplementsInterface")
shoulddo the trick.

Robert

Show quoteHide quote
"Phill. W" <P.A.Ward@o-p-e-n-.-a-c-.-u-k> wrote in message
news:dj05fm$f8m$1@yarrow.open.ac.uk...
> "Mike D Sutton" <ED***@mvps.org> wrote in message
> news:ezHmO0w0FHA.3300@TK2MSFTNGP15.phx.gbl...
> > You will also need to type-cast the object to it's interface in order
> > to access this property, I find a simple casting function works well
> > for this:
> >
> > Private Function MyAbstractClassCast( _
> >   ByVal inMyAbstractClass As clsMyAbstractClass _
> > ) As clsMyAbstractClass
> >     Set MyAbstractClassCast = inMyAbstractClass
> > End Function
> >
> > Dim X As clsSomeClassThatImplementsInterface
> > Set X = New clsSomeClassThatImplementsInterface
> > Call MsgBox(MyAbstractClassCast(X).OwnCrvID)
> > Set X = Nothing
>
> Am /I/ missing something or does the following not work just
> as well, and with rather less code?
>
> ' Create an AbstractClass-shaped variable ...
> Dim x As clsMyAbstractClass
>
> ' ... into which a class that implements it will "fit" ...
> Set x = New clsSomeClassThatImplementsInterface
>
> ' ... and use it "as" the Interface.
> Call MsgBox( x.OwnCrvID )
>
> Regards,
>     Phill  W.
>
>
Author
17 Oct 2005 4:37 PM
Phill. W
"Robert" <no***@nowhere.com> wrote in message
news:ONIcXox0FHA.4032@TK2MSFTNGP15.phx.gbl...
> Not quite.
> Set x = New clsSomeClassThatImplementsInterface causes a
> type mismatch, since x is declared as a different object type.

Not on /my/ machine, it doesn't.

This is basic Polymorphism - well, as good as VB6 can manage
it - any value can be assigned to a variable, so long as it "fits".
An Object that implements an Interface can be put into a variable
'dim'ed /as/ that Interface (and that's what we're talking about with
this Implementationless, "Abstract Class", I think.

Given :

[Abstract.cls]
Option Explicit
Public Property Get ID() As Integer
End Property

[Concrete.cls]
Option Explicit
Implements Abstract
Private Property Get Abstract_ID() As Integer
    Abstract_ID = 17
End Property

[form1.frm]
Sub Form_Load()
    Dim y As Abstract
    Set y = New Concrete
    Call MsgBox(y.ID)
End Sub

Does this not work for you?

Regards,
    Phill  W.
Author
17 Oct 2005 2:25 PM
Mike D Sutton
> Am /I/ missing something or does the following not work just
> as well, and with rather less code?
>
> ' Create an AbstractClass-shaped variable ...
> Dim x As clsMyAbstractClass
>
> ' ... into which a class that implements it will "fit" ...
> Set x = New clsSomeClassThatImplementsInterface
>
> ' ... and use it "as" the Interface.
> Call MsgBox( x.OwnCrvID )

Yep that works just fine as long as you don't need to access any of the
members of the implementing class, then you would need to cast the object
back to it's native type and you're in the same situation.  If you need to
access both the base interface and the classes members then you will either
need a second variable or a casting method as in my prior post, the latter
of which I personally prefer when working with larger projects that require
lots of interface casting - Just stick the casting method in a public module
and it's accessible from anywhere else in the project.  In the absence of an
"as" operator in the language IMO this is the next best thing.
Hope this helps,

    Mike


- Microsoft Visual Basic MVP -
E-Mail: ED***@mvps.org
WWW: Http://EDais.mvps.org/