interface odd behavior

M

masoud bayan

I've come across something in Interface implementation that I am not sure is
correct behavior in VB.NET (and maybe C#) or not?



Consider following example:



Public Interface IShape

Sub Draw()

End Interface



Public Class CCircle

Implements IShape

Public Sub DifferentDraw() Implements IShape.Draw

End Sub

End Class



According to OOP rules any CCircle object *IS-A* IShape object and also
IShape interface is a *CONTRACT* that guarantees all of its objects
implement methods in this contract. But in the following test, obj2 which is
supposed to obey above rules does not have access to Interface Draw()
method!!!???



Public Class Test

Public Sub Test()

Dim obj1 As IShape

obj1 = New CCircle

obj1.Draw()



Dim obj2 As CCircle

obj2 = New CCircle

obj2.DifferentDraw()

End Sub

End Class



Thanks

Masoud
 
C

Chris Dunaway

I think you need to cast obj2 to IShape in order to directly access the
interface members:

DirectCast(obj2,IShape).Draw()
 
M

masoud bayan

Chris Dunaway said:
I think you need to cast obj2 to IShape in order to directly access the
interface members:

DirectCast(obj2,IShape).Draw()


It is not a *have to* to cast a derived class to its base in hierarchy to
use base defined methods.

Think of ToString method of class Object, shall every class has a cast for
that?

Actually it is polymorphic behavior of OO languages that let us use a
derived class and access with the base methods.
 
I

Irfan

hi, Masud

When you actually do
obj2.DifferentDraw()
You are calling the IShape 's Draw method but implemented by you in Ccircle
class.
It will be of no use to call Interface methods, because they themselves are
empty anyway.

HTH
Irfan
 
C

Cor Ligthert

Masoud,

Think of ToString method of class Object, shall every class has a cast for
that?
The ToString() method is a member of Object. Object is not an interface
however the base class from which every class inherits.

Cor
 
M

masoud bayan

Ok.

I agree that ToString is defined in base class but what does it mean that
Interface is a Contract the guarantees every object derived from that
Interface implement s the methods in that contract?

Think someone defined IShape and then created a method as:



Public Sub(obj as IShape)

obj.draw()

End Sub



This method according to the test that I sent is not working anymore!!



Regarding "Tostring is method with implementation in base class", I think as
..net (and modern OOP languages) does not support multiple inheritance we
have interfaces but it does not mean inheritance and polymorphic behavior
should change. If we define an abstract method in an abstract class shall we
cast derived objects to base to be able to access the name of method?



Masoud
 
A

Armin Zingler

masoud bayan said:
I've come across something in Interface implementation that I am not
sure is correct behavior in VB.NET (and maybe C#) or not?



Consider following example:



Public Interface IShape

Sub Draw()

End Interface



Public Class CCircle

Implements IShape

Public Sub DifferentDraw() Implements IShape.Draw

End Sub

End Class



According to OOP rules any CCircle object *IS-A* IShape object and
also IShape interface is a *CONTRACT* that guarantees all of its
objects implement methods in this contract. But in the following
test, obj2 which is supposed to obey above rules does not have access
to Interface Draw() method!!!???


obj2 is not declared as IShape. You are using a different contract. The
contract name now is "CCircle" - that's how the variable is declare - and a
CCircle does have a DifferentDraw method. It does not have a Draw method
because it's not part of the contract.


Public Class Test

Public Sub Test()

Dim obj1 As IShape

obj1 = New CCircle

obj1.Draw()



Dim obj2 As CCircle

obj2 = New CCircle

obj2.DifferentDraw()

End Sub

End Class


Armin
 
J

Jay B. Harlow [MVP - Outlook]

masoud,
In addition to the other comments.

C# partially supports this with Explicit Interface Implementation.

http://msdn.microsoft.com/library/d.../en-us/csspec/html/vclrfcsharpspec_13_4_1.asp

I find the VB.NET to be stronger here, as I can rename the method and/or
change the visibility of the method. C# only allows you to hide the method.

| According to OOP rules any CCircle object *IS-A* IShape object and also
| IShape interface is a *CONTRACT* that guarantees all of its objects
| implement methods in this contract. But in the following test, obj2 which
is
| supposed to obey above rules does not have access to Interface Draw()
| method!!!???
Circle implements all the methods of IShape! however it simply renamed
and/or hide one or more of its methods. As you show, when an instance of a
Circle object is in an IShape variable or parameter you can access all of
IShape's methods.

Consider IDisposable. For some classes, such as Files, it makes more sense
to name IDisposable.Dispose method Close as its more logical to Close a file
rather then Dispose it.

If the IDisposable.Dispose method was required to be called Dispose it might
add confusion to other programmers using your class, especially if the class
offers both Dispose & Close.

Also consider IList, when defining a type safe list (such as CollectionBase)
its desired to hide most of the IList members, such as IList.Add(Object),
offering type safe versions PersonCollection.Add(Person) instead.

Consider:

Public Interface IShape
Sub Draw()
End Interface

Public Interface IDeckOfCards
Function Draw() As Card
End Interface

If you attempt to implement both interfaces, such as:

Public Class CCircle
Implements IShape
Implements IDeckOfCards

Public Sub Draw() Implements IShape.Draw
End Sub

Public Function Draw() As Card Implements IDeckOfCards.Draw

End Function

End Class

Without renaming, the above won't compile, as Draw is both a function & a
Sub. Further they do different things. IShape.Draw paints the shape on the
screen, while IDeckOfCards.Draw returns a card.

With renaming you can do:

Public Class CCircle
Implements IShape
Implements IDeckOfCards

Public Sub DrawShape() Implements IShape.Draw
End Sub

Public Function DrawCard() As Card Implements IDeckOfCards.Draw

End Function

End Class

Which avoids ambiguity in the public interface of Circle.

Hope this helps
Jay


| I've come across something in Interface implementation that I am not sure
is
| correct behavior in VB.NET (and maybe C#) or not?
|
|
|
| Consider following example:
|
|
|
| Public Interface IShape
|
| Sub Draw()
|
| End Interface
|
|
|
| Public Class CCircle
|
| Implements IShape
|
| Public Sub DifferentDraw() Implements IShape.Draw
|
| End Sub
|
| End Class
|
|
|
| According to OOP rules any CCircle object *IS-A* IShape object and also
| IShape interface is a *CONTRACT* that guarantees all of its objects
| implement methods in this contract. But in the following test, obj2 which
is
| supposed to obey above rules does not have access to Interface Draw()
| method!!!???
|
|
|
| Public Class Test
|
| Public Sub Test()
|
| Dim obj1 As IShape
|
| obj1 = New CCircle
|
| obj1.Draw()
|
|
|
| Dim obj2 As CCircle
|
| obj2 = New CCircle
|
| obj2.DifferentDraw()
|
| End Sub
|
| End Class
|
|
|
| Thanks
|
| Masoud
|
|
|
|
 
P

Phill. W

Irfan said:
When you actually do
obj2.DifferentDraw()
you are calling the IShape's Draw method

*Not* true. obj2 is defined as a CCircle and, therefore, can
only access the methods, etc. defined by CCircle.
To use methods defined via the IShape Interface, you must cast
the object to the Interface Type, as in

DirectCast( obj2, IShape ).Draw()

or, better,

Dim obj2 as IShape
obj2.Draw()
It will be of no use to call Interface methods, because they
themselves are empty anyway.

/If/ I understand this statement correctly (apologies if not) then
you've missed something fundamental about Interfaces.

The Interface /defines/ the methods, etc. that a class must
provide implementations for in order to be used as an "instance"
of the Interface. The Interface methods are not "empty" as you
describe; the actual code "behind" them is provided (somewhere)
in every Class that implements the Interface.

Regards,
Phill W.
 
M

masoud bayan

Thanks Jay, was great information.

Also thanks all others for their comments.



Just the last question:

There is only one problem though if someone defines an IShape interface with
Draw method and then a function as for feature objects of IShape:

Sub Test(obj as IShape)

Obj.Draw

End Sub



There is no guarantee that this function will work in future as maybe
somebody change Draw to something else in feature, except he explicitly cast
obj to Ishape in code.

So shall whenever we want to use an object in .net hierarchy and call a
method that we assume should be available in object (because of an interface
in hierarchy) first cast it to interface?



Masoud
 
J

Jay B. Harlow [MVP - Outlook]

masoud,
| There is only one problem though if someone defines an IShape interface
with
| Draw method and then a function as for feature objects of IShape:
I don't see a problem...

| Sub Test(obj as IShape)
|
| Obj.Draw
|
| End Sub

| There is no guarantee that this function will work in future as maybe
| somebody change Draw to something else in feature, except he explicitly
cast
| obj to Ishape in code.
Yes there is a "guarantee". The "Implements IShape.Draw" on the Sub's
declaration is the "guarantee".

| > Public Sub Draw() Implements IShape.Draw
| > End Sub

When you pass the Circle object to the IShape parameter, the Test function
will call the method labeled with "Implements IShape.Draw", independent of
what you named the method itself in Circle...

C# does not use the "Implements IShape.Draw" syntax, which is why the method
in C# either needs to be public or it needs to use the Explicit Interface
Implementation syntax. I find the "Implements IShape.Draw" syntax to be far
more flexible.

Hope this helps
Jay


| Thanks Jay, was great information.
|
| Also thanks all others for their comments.
|
|
|
| Just the last question:
|
| There is only one problem though if someone defines an IShape interface
with
| Draw method and then a function as for feature objects of IShape:
|
| Sub Test(obj as IShape)
|
| Obj.Draw
|
| End Sub
|
|
|
| There is no guarantee that this function will work in future as maybe
| somebody change Draw to something else in feature, except he explicitly
cast
| obj to Ishape in code.
|
| So shall whenever we want to use an object in .net hierarchy and call a
| method that we assume should be available in object (because of an
interface
| in hierarchy) first cast it to interface?
|
|
|
| Masoud
|
|
|
|
| | > masoud,
| > In addition to the other comments.
| >
| > C# partially supports this with Explicit Interface Implementation.
| >
| >
|
http://msdn.microsoft.com/library/d.../en-us/csspec/html/vclrfcsharpspec_13_4_1.asp
| >
| > I find the VB.NET to be stronger here, as I can rename the method and/or
| > change the visibility of the method. C# only allows you to hide the
| method.
| >
| > | According to OOP rules any CCircle object *IS-A* IShape object and
also
| > | IShape interface is a *CONTRACT* that guarantees all of its objects
| > | implement methods in this contract. But in the following test, obj2
| which
| > is
| > | supposed to obey above rules does not have access to Interface Draw()
| > | method!!!???
| > Circle implements all the methods of IShape! however it simply renamed
| > and/or hide one or more of its methods. As you show, when an instance of
a
| > Circle object is in an IShape variable or parameter you can access all
of
| > IShape's methods.
| >
| > Consider IDisposable. For some classes, such as Files, it makes more
sense
| > to name IDisposable.Dispose method Close as its more logical to Close a
| file
| > rather then Dispose it.
| >
| > If the IDisposable.Dispose method was required to be called Dispose it
| might
| > add confusion to other programmers using your class, especially if the
| class
| > offers both Dispose & Close.
| >
| > Also consider IList, when defining a type safe list (such as
| CollectionBase)
| > its desired to hide most of the IList members, such as
IList.Add(Object),
| > offering type safe versions PersonCollection.Add(Person) instead.
| >
| > Consider:
| >
| > Public Interface IShape
| > Sub Draw()
| > End Interface
| >
| > Public Interface IDeckOfCards
| > Function Draw() As Card
| > End Interface
| >
| > If you attempt to implement both interfaces, such as:
| >
| > Public Class CCircle
| > Implements IShape
| > Implements IDeckOfCards
| >
| > Public Sub Draw() Implements IShape.Draw
| > End Sub
| >
| > Public Function Draw() As Card Implements IDeckOfCards.Draw
| >
| > End Function
| >
| > End Class
| >
| > Without renaming, the above won't compile, as Draw is both a function &
a
| > Sub. Further they do different things. IShape.Draw paints the shape on
the
| > screen, while IDeckOfCards.Draw returns a card.
| >
| > With renaming you can do:
| >
| > Public Class CCircle
| > Implements IShape
| > Implements IDeckOfCards
| >
| > Public Sub DrawShape() Implements IShape.Draw
| > End Sub
| >
| > Public Function DrawCard() As Card Implements IDeckOfCards.Draw
| >
| > End Function
| >
| > End Class
| >
| > Which avoids ambiguity in the public interface of Circle.
| >
| > Hope this helps
| > Jay
| >
| >
| > | > | I've come across something in Interface implementation that I am not
| sure
| > is
| > | correct behavior in VB.NET (and maybe C#) or not?
| > |
| > |
| > |
| > | Consider following example:
| > |
| > |
| > |
| > | Public Interface IShape
| > |
| > | Sub Draw()
| > |
| > | End Interface
| > |
| > |
| > |
| > | Public Class CCircle
| > |
| > | Implements IShape
| > |
| > | Public Sub DifferentDraw() Implements IShape.Draw
| > |
| > | End Sub
| > |
| > | End Class
| > |
| > |
| > |
| > | According to OOP rules any CCircle object *IS-A* IShape object and
also
| > | IShape interface is a *CONTRACT* that guarantees all of its objects
| > | implement methods in this contract. But in the following test, obj2
| which
| > is
| > | supposed to obey above rules does not have access to Interface Draw()
| > | method!!!???
| > |
| > |
| > |
| > | Public Class Test
| > |
| > | Public Sub Test()
| > |
| > | Dim obj1 As IShape
| > |
| > | obj1 = New CCircle
| > |
| > | obj1.Draw()
| > |
| > |
| > |
| > | Dim obj2 As CCircle
| > |
| > | obj2 = New CCircle
| > |
| > | obj2.DifferentDraw()
| > |
| > | End Sub
| > |
| > | End Class
| > |
| > |
| > |
| > | Thanks
| > |
| > | Masoud
| > |
| > |
| > |
| > |
| >
| >
|
|
 
H

Herfried K. Wagner [MVP]

masoud bayan said:
There is only one problem though if someone defines an IShape interface
with
Draw method and then a function as for feature objects of IShape:

Sub Test(obj as IShape)

Obj.Draw

End Sub



There is no guarantee that this function will work in future as maybe
somebody change Draw to something else in feature, except he explicitly
cast
obj to Ishape in code.

The type of the 'obj' parameter is already 'IShape', thus no cast is
necessary.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top