Front-end week Front-end week
This week up to 80% off on HTML/CSS and JavaScript courses.

Lesson 14 - Interfaces in VB.NET

In the previous lesson, Diary with a database in VB.NET, we practiced working with List collections and created an electronic diary in Visual Basic .NET. In today's tutorial, we'll be getting back into some more theoretical matters. We're going to unveil yet another utility of the object-oriented programming world!

Interface

When one refers to an object's interface, they are referring to how an object is visible from the outside. We already know that an object contains methods that can be set as private or public. The object's interface consists of its public methods, which is the way we communicate with certain types of objects. We have already dealt with public methods in previous lessons, e.g. the ones we set up for our arena warrior. The Warrior class we made had the following public methods:

  • Sub Attack(enemy As Warrior)
  • Sub Defend(hit As Integer)
  • Function Alive() As Boolean
  • Sub SetMessage(message As String)
  • Function GetLastMessage() As String
  • Function HealthBar() As String

If we store a Warrior class instance into a variable, we are able to call the Attack() or Defend() methods on it. Nothing new, right?

As a matter of fact, we are able to declare an interface separately, sort of like we do with classes, and we would then be able to use it as a data type.

We'll give it a go, but on a simpler class than the Warrior class we made. We'll start by creating a new project, a console application, naming it InterfaceSample, and adding a simple class. In my opinion, theoretical concepts should be explained using light examples, meaning not as serious. With that all being said, let's make a bird class! Our bird will be able to chirp, breathe and peck. Our Bird class will look something like this:

Public Class Bird

    Public Sub Chirp()
        Console.WriteLine("♫ ♫ ♫")
    End Sub

    Public Sub Breathe()
        Console.WriteLine("Breathing...")
    End Sub

    Public Sub Peck()
        Console.WriteLine("Peck, peck!")
    End Sub

End Class

Done! Now, let's move to Module1.vb and create a bird instance:

Dim bird As Bird = New Bird()

Once you've created an instance of the bird class, write whatever you called the instance, in my case, it is "bird", and add a dot right after it. Visual Studio will then display all of its class methods (you can also invoke IntelliSense by pressing Ctrl + Space):

Bird methods in VB.NET

We now see everything that we can call on the bird instance. The 3 methods we just now implemented are there as well as some others that all objects have from its base.

Now let's create an interface for our bird. We'll use the Interface keyword to do just that. In VB.NET, it's a good practice to prefix the Interface with "I" (as in Interface). Right-click on the project, and choose Add new item -> Interface.

New interface in Visual Studio

An empty interface will be added to our project. We'll add the headers of methods which this interface will require. The implementation itself, method content, is added later by the class that implements the interface.

Let's add method headers to the IBird interface, we'll purposely omit one of them and only add chirping and breathing:

Public Interface IBird
    Sub Chirp()
    Sub Breathe()
End Interface

We don't specify the Public modifier since an interface contains public methods only. It wouldn't make sense otherwise since it specifies how to work with an object from the outside.

Let's go back to Module1.vb and change the line with the bird variable so it won't be longer of the Bird type, but of the IBird type:

Dim bird As IBird = New Bird()

What the code above means is that in the bird variable, we expect an object that contains the methods specified in the IBird interface. Visual Studio reports an error since the Bird class doesn't implement the IBird interface yet. Although it does have the needed methods, it must first be informed that it implements this interface. Let's move to the Bird class and let it implement the IBird interface. We do it in the same way as when we want a class to inherit from another, we just use the Implements keyword for that:

Public Class Bird
    Implements IBird
    . . .

We also have to specify which methods from the class implements which method from the interface(s). We use the Implements keyword for it as well, this time after the methods definitions. The Bird class will now look like this:

Public Class Bird
    Implements IBird

    Public Sub Chirp() Implements IBird.Chirp
        Console.WriteLine("♫ ♫ ♫")
    End Sub

    Public Sub Breathe() Implements IBird.Breathe
        Console.WriteLine("Breathing...")
    End Sub

    Public Sub Peck()
        Console.WriteLine("Peck, peck!")
    End Sub

End Class

When we go back to Module1.vb, the line with the variable of the IBird type no longer causes an error. The Bird class correctly implements the IBird interface. Meaning that Bird instances can now be stored in variables of this type.

Now just for completeness' sake, let's see what happens when we remove a method from the class, which is required by the interface, like the Chirp() method. Visual Studio will warn us that the implementation is not complete. Once you have visual confirmation of the interface's dependency on the class, put the method back where it belongs.

Let's write bird with a dot after it. Again, Visual Studio will offer the following methods:

Methods of a bird stored in a variable of the IBird interface

We can see that now we can call only the methods provided by the interface on the instance. That's because the bird is now a variable of the IBird type, not the Bird type. Meaning that we cannot call the Peck() method because we did not add it to the interface.

Why did we leave it out in the first place, you may ask? Lots of potential reasons, we've already encountered one of them. By using an interface, we simplify a complex object and expose only the parts needed in a certain part of the program.

Also, I must add that interfaces cannot be instantiated. In other words, this code will not work:

' this code won't work
Dim bird As IBird = New IBird()

Multiple inheritance

Visual Basic .NET, like most programming languages, doesn't support multiple inheritance. Meaning that we can't inherit one class from more than one other class. Mainly, because method naming collisions could very well occur when multiple classes containing methods with the same name inherit their methods into another class. Multiple inheritance is often worked around using interfaces because we are allowed to implement as many interfaces in a class as we want. A class of the sort only allows us to work with its instances in ways that we want to. We wouldn't have to worry about of what object type it actually is, or what it provides beyond the interfaces.

Now let's add an ILizard interface to our project. Lizards will be able to breathe and crawl:

Public Interface ILizard
    Sub Crawl()
    Sub Breathe()
End Interface

Next, we'll try "multiple inheritance", more accurately, implement multiple interfaces by a single class. We'll add a Pterodactyl.vb class to the project. It will implement IBird and ILizard interfaces:

Public Class Pterodactyl
    Implements ILizard, IBird

End Class

If we hover the mouse above each interface, i.e. click on ILizard or IBird, there is a "light-bulb" shortcut to Implement the Interface in the context menu. It may also happen automatically when you write an interface name to implement. Visual Studio will then automatically generate the necessary class methods.

Automatic interface implementation in Visual Studio

After having both interfaces implemented, the code will look like this. Notice that there are 2 Breathe() methods since the method is required both by IBird and ILizard:

Public Class Pterodactyl
    Implements ILizard, IBird

    Public Sub Breathe() Implements ILizard.Breathe
        Throw New NotImplementedException()
        End Sub

        Public Sub Chirp() Implements IBird.Chirp
        Throw New NotImplementedException()
        End Sub

        Public Sub Crawl() Implements ILizard.Crawl
        Throw New NotImplementedException()
        End Sub

        Private Sub IBird_Breathe() Implements IBird.Breathe
        Throw New NotImplementedException()
        End Sub

End Class

Since the breathing will be always the same, let's remove the IBird_Breathe() method and add IBird.Breathe after the Implements keyword of the first Breathe() method.

Now all we have to do is specify what we want each method to do:

Public Sub Breathe() Implements ILizard.Breathe, IBird.Breathe
    Console.WriteLine("I'm breathing...")
End Sub

Public Sub Crawl() Implements ILizard.Crawl
    Console.WriteLine("I'm crawling...")
End Sub

public Sub Chirp() Implements IBird.Chirp
    Console.WriteLine("♫ ♫♫ ♫ ♫ ♫♫")
End Sub

That's pretty much it! Now, let's add an instance of the Pterodactyl class in Module1.vb:

Dim pterodactyl As Pterodactyl = New Pterodactyl()

Make sure, that it has both the bird and lizard methods:

Bird and lizard methods on a pterodactyl instance

We'll stick to interfaces for a little while since there is much more to them that we haven't covered. In the next lesson, Type casting and object hierarchy in VB.NET, you will learn more advanced techniques of the object-oriented programming.


 

 

Activities (9)

 

 

Comments
Display older comments (2)

Avatar
David Capka
ICT.social team
Avatar
David Capka:4. February 12:29

Hi Ama, I don't see any problem with the article. Can you, please, quote the part you find confusing? I believe the sentence:

By using an interface, we simplify a complex object and expose only the parts needed in a certain part of the program.

Explains the advantages of using interfaces quite well.

Reply 4. February 12:29
You can walk through a storm and feel the wind but you know you are not the wind.
Avatar
Ama .
Member
Avatar
Ama .:4. February 12:51

At the end, the article says

Make sure, that it has both the bird and lizard methods:

As if the Pterodactyl class was derived from IBird and ILizard, whilst I belive what is happening is Pterodactyl is the "base" for both IBird and ILizard. Hence I do not understand how we can pretend having acheived multiple inheritence as if Pterodactyl was a combination of Lizard and Bird, whilst actually ILizard is a simplified version of Pterodactyl, and the same goes for IBird.

An interface would be an alternative to classes multiple inheritence if an interface had the ability to be implemented by several classes (1 interface from 2 classes, rather than 2 interfaces from 1 class). Is this possible?

 
Reply 4. February 12:51
Avatar
David Capka
ICT.social team
Avatar
Replies to Ama .
David Capka:4. February 13:11
  • "Make sure, that it has both the bird and lizard methods" - Since the Pterodactyl class implements both IBird and ILizard interfaces, it says you should check for yourself there are methods from both interfaces available. What's wrong with that?
  • "I do not understand how we can pretend having acheived multiple inheritence as if Pterodactyl was a combination of Lizard and Bird" - It is a combination of Lizard and Bird. Look at it :) - https://www.google.com/search?…
  • "An interface would be an alternative to classes multiple inheritence if an interface had the ability to be implemented by several classes" - You got it the other way around, a class can implement multiple interfaces, thus it can be derived from the interfaces of other multiple classes if these have been declared as interfaces. However, you have to implement the method bodies, so it's not a true inheritance. The article says you can work around the lack of multiple inheritance using interfaces, not that it actually is multiple inheritance.
Reply 4. February 13:11
You can walk through a storm and feel the wind but you know you are not the wind.
Avatar
Ama .
Member
Avatar
Replies to David Capka
Ama .:4. February 14:41

"a class can implement multiple interfaces" = Multiple interfaces can be derived from one class. Just like multiple classes can be derived from a base class.
The difference being that when we define a sub-class inherited from a base-class, we add functionnalities; whilst when we define an interface implemented by a class, we remove functionnalities (as is said in the article, "we simplify a complex object and expose only the parts needed").

First one defines the complex object, then one simplifes it by deriving as many interfaces as needed from that complex object, not the other way around. It is not because the verb "implement" is used on the active form, that the flow goes the same way.

Multiple inheritance is often worked around using interfaces because we are allowed to implement as many interfaces in a class as we want.

I still do not understand where the workaround is. Is it saying that if I would like to have class A, class B, and class AB as inherited from both A and B, the solution is to actually create class AB with all the required members, and then if I need to only deal with what was supposed to be class A or classB, I can create interfaces A and B for that purpose?

 
Reply 4. February 14:41
Avatar
David Capka
ICT.social team
Avatar
Replies to Ama .
David Capka:5. February 6:17

There are multiple problems interfaces can solve for you. It's not like they only hide ("remove") functionality.

About subclassing - Yes, when you inherit a class from a base class, you are typically adding functionality. When you declare an interface and implement it in a class, you're saying "This class is required to have the methods this interface specifies" That's all what happens. With interfaces, you force a class to have a given set of methods. Then you have to implement the methods by yourself, it doesn't get inherited coz the interface methods are always empty.

Now what's the point of doing that? It's sort of generalization. Imagine you have 100 classes representing various objects, e.g. in a computer game. There are people, cars, trees, buildings... Let's say you shoot an object. Some objects can be destroyed, some can't. In this situation, you aren't interested in a particular object, but in a particular functionality. You can ask whether the object, e.g. a tree, implements the IDestroyable interface. If so, you know it has to have the Destroy() method and you simply call it. You cast the object to the type of this interface to be able to call this functionality. All the other parent class' and other interfaces' methods are now unavailable.

Is it saying that if I would like to have class A, class B, and class AB as inherited from both A and B...

You cannot inherit a class from 2 classes. It just can't happen. That's why when you need 2 sets of functionalities in one class, you create 2 interfaces for these functionalities and then implement them in the AB class. It's the only way. That's how we could have both bird and lizard methods in a single class. We created interfaces for both sets of functionalities and then implemented them. From the type system's point of view, Pterodactyl now behaves as a combination of the Lizard and Bird classes.

Edited 5. February 6:22
Reply 5. February 6:17
You can walk through a storm and feel the wind but you know you are not the wind.
Avatar
Ama .
Member
Avatar
Ama .:5. February 6:58

Many thanks David for the detailed answer.
Just one clarification, when you say

You can ask whether the object, e.g. a tree, implements the IDestroyable interface.

Does that mean several objects can implement the same interface? In which case I am confused: since the members of an interface are implemented within a given class block (as opposed to within the interface block), then if two classes implement the same interface, how does the compilier know which class block to use?

 
Reply 5. February 6:58
Avatar
Ama .
Member
Avatar
Ama .:5. February 7:06

Edit: Following this I did some extra research. It appears that indeed a single interface can be implemented by several classes. So I now find this article extremely confusing in the sense that the whole point of interfaces is to use them with multiple classes, but here in the article we use one class to deal with multiple interfaces, which is good to know but as I now understand that is not really what interfaces are for...

 
Reply  +1 5. February 7:06
Avatar
David Capka
ICT.social team
Avatar
Replies to Ama .
David Capka:5. February 7:31

There are the IBird and ILizard interfaces which are implemented by the Bird, Lizard and Pterodactyl class. I find it clear you can implement a single interface in multiple classes.

Reply 5. February 7:31
You can walk through a storm and feel the wind but you know you are not the wind.
Avatar
Ama .
Member
Avatar
Ama .:5. February 8:03

Visual Basic .NET, like most programming languages, doesn't support multiple inheritance. Meaning that we can't inherit one class from more than one other class.

The author says multiple inheritance = class AB based on class A and class B.
It says that is not possible.

Next, we'll try "multiple inheritance", more accurately, implement multiple interfaces by a single class.

The author says multiple inheritance = interface A1 and A2 based on class A.
It says that is the solution to the above problem. Well, that is not a solution to the above problem, and moreover that can already be done through classic class inheritance.

He is confused about what he means by Multiple inheritence.. The purpose of inheritence is to avoid rewriting existing code, but since the code is in the class block, then it is the interface which would inherit from the code in the class, no the other way around.

Hence, he should have said "Next, we'll try 'multiple inheritance', more accurately, having a single interface implemented by several classes".

And conclude the article on

Dim bird1 As IBird = New Bird()
Dim bird2 As IBird = New Pterodactyl()
Dim bird3 As IBird = New Dodo()
Dim bird4 As IBird = New Eagle()

rather than

Dim pterodactyl As Pterodactyl = New Pterodactyl()

It's a shame because the first half of the article is good.

Edited 5. February 8:04
 
Reply 5. February 8:03
Avatar
David Capka
ICT.social team
Avatar
Replies to Ama .
David Capka:5. February 11:37

I see how you see it :) But this way makes it confusing for me. I guess we all think differently.

Next, we'll try "multiple inheritance", more accurately, implement multiple interfaces by a single class.

This sentence shouldn't say "interface A1 and A2 based on class A.", but "class A based on interface A1 and A2". As I understand it, the phrase "implement an interface" means to add "Implements A1" to your class. I can see somebody can find it confusing, didn't think about that before.

"Next, we'll try 'multiple inheritance', more accurately, having a single interface implemented by several classes".

You could say this, but I find it confusing from my understanding to this article. The chapter is talking about adding a Pterodactyl class (a single class) based on 2 interfaces (IBird and ILizard). "Several classes" would confuse me here.

Reply  +1 5. February 11:37
You can walk through a storm and feel the wind but you know you are not the wind.
To maintain the quality of discussion, we only allow registered members to comment. Sign in. If you're new, Sign up, it's free.

10 messages from 12 displayed. Show all