Need info on Class Interfaces

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 :stuck_out_tongue:

OK, maybe I will call up this thread each day and change the post that answered my question :slight_smile:

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]

1 Like

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 :slight_smile:

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]