Hi, I am slowly getting to grips with OOP, but the concept of Interfaces still allude me. In my program I have two classes. Both of them have a getClassNumber method and a getClassName method. They both seem to work OK, I have been working the program for quite a while and the result I get after each run is what I expect. But because I have those two methods of the same name in each class, should I create a New Interface of each of those names? If so, what is the advantage of doing that rather than just creating the methods as I have done. The only thing I can think is that if I give away my classes to someone else, then they are forced into using those methods - is that the main reasons for interfaces? As that will probably never happen (my skills are not enough to give anything away), then perhaps I can forget about Interfaces. Any clarification would be appreciated.
An interface defines an API (a set of methods) that all classes that implement the interface agree to adhere to. In other words, if the interface specifies a method getClassNumber, then for any class that implements the interface, you can be assured that calling getClassNumber is supported. An interface is therefore a sort of contract between the developer and the compiler. If a class purports to implement the interface, the compiler will enforce that it has all the required methods.
In addition, the interface becomes a new data type. You can treat it just like a class definition. For example:
Interface ClassInfoProvider
Function getClassNumber() as Integer
End Interface
Class ClassA
Implements ClassInfoProvider
Function getClassNumber() as Integer
return 1
End Function
End Class
Class ClassB
Implements ClassInfoProvider
Function getClassNumber() as Integer
return 2
End Function
End Class
dim a as ClassA
dim b as ClassB
dim c as ClassA
dim n as integer
c = a
n = c.getClassNumber // ok, returns 1
c = b // compile error
// OR
dim c as object
c = a // ok
c = b // ok
n = c.getClassNumber // compile error
//But
dim c as ClassInfoProvider
c = a
n = c.getClassNumber // ok, returns 1
c = b
n = c.getClassNumber // ok, returns 2
ClassA and ClassB have to common Super, but you can still define a variable that will hold either of them and call a predifined set of methods (those in the interface).
Hope that helps.
Thatâs interesting that it is also useful in your own classes, seeing as you should know what methods each class must have (especially if some of them are the same).
I wasnât aware that they both had to have the same Super. So I suppose this would mean I would create a Class âClassInfoâ and include in that all the properties that are going to be common to the other classes. Then I would create a Class âSectionClassesâ with CassInfo as its Super, and OrderedClasses, also with ClassInfo as its Super. Then an Interface ClassInfoProvider (as you suggested), which would be added to both sectionClasses and orderedClasses. Is that correct?
Interfaces make it so you do NOT have to have a common super
Interfaces make it so you can have ANY class implement some well defined set of methods & they will exist (they dont have to DO anything useful) but they will exist
And because an interface is a new type, juts like a class, you can do something like the following
- note classa & classb have no common super and share nothing EXCEPT they both implement the interface
[code]Interface ClassInfoProvider
Function getClassNumber() as Integer
End Interface
Class ClassA
Implements ClassInfoProvider
Function getClassNumber() as Integer
return 1
End Function
End Class
Class ClassB
Implements ClassInfoProvider
Function getClassNumber() as Integer
return 2
End Function
End Class
dim a as new ClassA
dim b as new ClassB
dim c as ClassInfoProvider
dim n as integer
c = a
n = c.getClassNumber // ok, returns 1
c = b
n = c.getClassNumber // ok, returns 2[/code]
I wouldnât use an interface in that scenario. I would have ClassInfo define both methods, but leave them empty. Then have SectionClasses and OrderedClasses provide their own implementations for those methods. Then any variable dimmed as type âClassInfoâ can call getClassNumber and get the appropriate value for the subclass.
Class ClassInfo
Function getClassNumber() as Integer
msgbox "Please implement getClassNumber in your subclass!"
End Function
End Class
Class SectionClasses
Inherits ClassInfo
Function getClassNumber() as Integer
return 1
End Function
End Class
Class OrderedClasses
Inherits ClassInfo
Function getClassNumber() as Integer
return 2
End Function
End Class
dim a as SectionClasses
dim b as OrderedClasses
dim c as ClassInfo
dim n as integer
c = a
n = c.getClassNumber // ok, returns 1
c = b
n = c.getClassNumber // ok, returns 2
Edit: Norman beat me to it.
Note that in both cases, the emphasis is on abstraction, using the objects without knowing their exact implementation, or even their type.
Thanks to both of you. I think I have enough information now to experiment with what you have told me. (I still think I might save my project with a different name so I donât completely stuff up what works already!) With the ability to treat the Interface as a new DataType I can see where this could be useful.
I wish I could say that two replies have answered my question, but I will go with Tim, but only because he was first.
Bah what does tim know
OK, maybe I will call up this thread each day and change the post that answered my question
or you can combine the 2 approaches
define an interface
then define a new class that implements that interface
and the any subclasses of that class are also implementers of that interface (since the parent class implements it)
you can mix & match in lots of fun ways
Now why might you do this vs just use the interface ?
Suppose you have a root class - Animal
And then you subclass Animal and have Dog, Fish and Bird
And the parent class, Animal, defines a âmoveâ method so each sub either overrides it or inherits the parents implementation
Each subclass then could implement Move in a different way as dogs fish & birds move in different ways
Then you extend your software and you now have âvehiclesâ
And this has subclasses Car, Ship, Airplane
They arenât animals BUT they move
So the Vehicle parent class has a move method and again each subclass has a different one as cars hips & airplanes move in different ways
No IF you create an interface MovableObject with one method âmoveâ then you can make Animal implement movable object, and vehicle implement movable object (since both already have a suitable move method)
Now those two have no common super but they are both âmovable objectsâ
And each animal subclass, dogs fish & birds, are also, by extension, movable"
As is each vehicle subclass
So you could literally do
[code]dim mo() sas MovableObject()
mo.append new Dog // its a movable object remember ?
mo.append new Car // this one too
for each o as MovableObject in mo
o.Move
next[/code]
Shhhh. Donât blow my cover.
Another note that I donât think was explicitly stated but is very useful (though I probably just missed this while skimming over Norman and Timâs responses): classes can implement multiple interfaces, which makes interfaces even more useful. A class can only have one super, but can implement as many interfaces as youâd like.
@Cliff Strange you might want to have a look at this on the Xojo Webinar site.
I liked it, but that video will take a bit of looking at and repeating before I completely understand it :o
Those abstract implementation never did anything for me as in WHY I should use something like an interface.
So let me try something different: an interface allows you to treat different things the same.
As example you have a house where you want to open the doors and the windows and the cat flap. You give each object the method to open itself. Then you make a list of all objects that can be opened. Now you loop over the openable things (thatâs your interface) and give the open command. Itâs not important what exactly the openable object is or how itâs open command works. There is a open method, the object obeys the openable interface and thatâs it.
Hi Beatrix
Are you saying that you would use a class interface, but not bother with the Observer Pattern?
Depends on what you want to do
The observer pattern is just one way of using interfaces, but the webinar is a good demo. If you look at the EEiOS example youâll see on the customerview how the iOSTableDataSource interface is implemented.
A nice trick about interfaces is they can expose private or protected methods.
[code]Interface MyInterface
Sub foo()
End Interface
Class MyClass Implements MyInterface
Private Sub foo()
Msgbox âbooâ
End Sub
End Class
dim c As new MyClass
//canât call c.foo, itâs private
dim i As MyInterface = c
i.foo //ok
[/code]
iâve used this when I want one class to have special access to another that should otherwise be private. Thereâs other ways to do this, and it doesnât keep anything else from accessing through the interface but itâs clean, simple and good enough to prevent accidental access.
Another nice feature is you can rename a method that implements the interface. For example, you may want to add two interfaces which contain the same method name and signature to a class, but those methods should be different for each interface. Or the class may already contain a method that conflicts with an interface to be added. Basically thereâs a naming conflict.
No worries. Add a method for implementing the interface method but give it a different name. Then context-click on the method in the navigator and choose âShow Implementsâ. A new âImplementsâ field appears under Scope where you enter what interface method this method should implement.
Example, this MyClass has a pre-existing foo method. To add the interface with a distinct foo implementationâŠ
[code]Interface MyInterface
Sub foo()
End Interface
Class MyClass Implements MyInterface
Sub foo()
Msgbox âfooâ
End Sub
Sub theInterfacesFoo() Implements MyInterface.foo
Msgbox âtheInterfacesFooâ
End Sub
End Class
//âMyInterface.fooâ is what goes in the Implements field
dim c As new MyClass
c.foo //âfooâ
dim i As MyInterface = c
i.foo //âtheInterfacesFooâ[/code]