Check out a free preview of the full C# and .NET Basics course
The "Interfaces" Lesson is part of the full, C# and .NET Basics course featured in this preview video. Here's what you'd learn in this lesson:
Spencer explains interfaces as similar to micro abstract classes with no inheritance hierarchy. He demonstrates how to declare and implement an interface in code and discusses the use cases and advantages of interfaces over abstract classes.
Transcript from the "Interfaces" Lesson
[00:00:00]
>> Spencer Schneidenbach: So up to this point, we've talked about classes, we've talked about inheritance of classes, a really important topic to cover. So we're gonna talk about probably the most important implementation of inheritance in C#, which is what's called an interface. So an interface is essentially, think of it like a micro abstract class with no inheritance hiring, you can actually inherit from other interfaces, which we'll talk about, but it's essentially not a class at all, it's a contract.
[00:00:29]
And what I mean by that is that it's something that says we're gonna define a specific aspect of behavior that you have to implement, but we're not gonna be opinionated about how you implement it. Let's take this IDatabase. So first of all naming convention, interfaces are named always in Pascal case and always prefixed by an I.
[00:00:53]
That's an important part of interfaces to know, when you see I something, unless it's a full word that starts with I, you should think immediately interface. So let's take this example for instance. So in the real world, in the programming world, there's dozens of different ways and different means of connecting, or there's dozens of different database products that exist in the market.
[00:01:17]
SQL Server is one that's Microsoft's, Postgres is another, there's Oracle, there's a huge ton of them. I mainly use SQL Server and Postgres. And between those two systems, they are different database systems, they have similar but different authentication requirements, they have similar but different ways of communicating with those databases.
[00:01:42]
So what this interface is meant to define is that we know that we wanna connect to a database, and we know we wanna be able to disconnect to the database, but how we do that is up to you. Inheritance, first of all, why use interfaces at all? First of all, multiple inheritance is not a thing, if I flip it back to my code, and for instance, I define a, skip this back to a state, there we go.
[00:02:13]
And I define a separate robot class. I can't have an hourly employee that inherits from a robot and an employee, so multiple inheritance just does not exist. C#, however, has interfaces to allow you to kind of get multiple inheritance, it's essentially, it's what's called implementation. Instead of inheriting from an object, you implement an interface.
[00:02:39]
So it allows us to have a lot of the similar functionality as multiple interfaces without all of the problems that comes with multiple inheritance. They also emphasize composability, so it essentially allows you to take an object and give it a few different behaviors that may be important to other objects in the world that you've created.
[00:03:02]
And this promotes a flexible kind of modular code design, and it makes it easy to extend and change code. And understanding interfaces is really crucial to understanding how, especially when we get to the ASP.NET Core course, interfaces become especially important to understand because they're everywhere. So, I think that the main thing is that they provide no behaviors by default, they're basically saying, I need you to implement this behavior for me.
[00:03:33]
It's wanting to tell you about how a contract should be filled, but not how a contract should be fulfilled, it does not wanna tell you how to do it, doesn't wanna tell you how to do your job. So you can think of classes as defining the behaviors and the properties of the thing, and interfaces define the thing's shape, general shape, without opinions about the behavior.
[00:03:54]
It may define properties, it may define methods, it just depends on the interface. So an interface is declared very simply by instead of public class, you have public interface. And then you have the name of the interface, again, usually prefixed with I. You can declare them without the I, but C# is going to tell you now you really should do that and provide a link to documentation explaining why.
[00:04:23]
For consistency, prefix it with an I. And you're gonna see that there's no behaviors, there's no compiler, errors, there's no warnings. It's because we've simply defined this interface by itself, and we've done it in a way that C# is totally okay with. You can define an interface and then not use it and give it no behaviors, but the moment you implement that interface on a class is when it becomes important.
[00:04:47]
So let me show you kind of what that would look like in a very, it's a little bit contrived, but it will work. So if we have a SqlDatabase. So let's call this a SqlServerDatabase, and we live in and call it MicrosoftSqlServer, just to say that this is a separate product, right?
[00:05:04]
I'm gonna go ahead and delete the implementation. First thing you're gonna see is that we get a little squiggles, it says, this doesn't implement this interface member, it doesn't implement connect, disconnect, or is connected. You're forced to declare all three or else you will get a compiler error.
[00:05:21]
So this is where the different behavior comes in, right? So you have a class that is the way that we connect to MicrosoftSqlServer, but again, it's different than the way that we would do if we were declaring a PostgresDatabase, that implements IDatabase. It's gonna have a totally different set of, like I said, authentication or negotiation about how to connect and how to send and receive data.
[00:05:50]
They're gonna be different because they're different database systems. So it's gonna want you to fulfill this contract as well same as that. I'm gonna use my tooling to do it, so command., and I'm gonna say implement interface, and you're gonna see that it's going to kind of implement it.
[00:06:06]
It's gonna just define the structure, but it's also gonna say, hey, we're gonna throw a bunch of not implemented exceptions to say you need to fill in these parts of it. So we'll go ahead and do that real quick, same as below. And so this might be Console.WriteLine Connected to Postgres.
[00:06:26]
Let's pretend this is a Postgres connection. Do the same thing down here, boom. Disconnected from Postgres, okay? So again, abstract class. When you inherit from a class, it's called inheriting from it, when you implement an interface, you're implementing it. A couple of things to note, C#, they introduced something called default implementations in interfaces.
[00:07:00]
Which is a behavior that's kind of one of those mind pretzel things that I saw and my eyes crossed. It's not something that I do ever and that's because that's really not the point of an interface. These have a very, very narrow use case, but in theory, you can give a interface now a default behavior and then not force the implementing class to actually override that behavior.
[00:07:26]
So you could say Console.WriteLine, why does this exist? This is one of those features of C# that I simply just don't agree with, and I don't agree with it because interfaces are meant to be kind of a clean contract. Just implement this behavior and we're good. So Spencer doesn't use them, there's my little spicy take, and I don't, I just haven't seen them in the wild, I think most people respect interfaces for what they're meant to be.
[00:07:55]
A couple of other kinda notes, kind of curiosities if you will, so there's what's called a static abstract method. And so what this is, essentially, is you can define a static method in a implementing class, you can force that class to define a static method. Again, something that is a very narrow use case, and actually is slightly more useful in my opinion, than default implementations.
[00:08:23]
I have not written one of these in real life, I will say that I'm showing it to you so that you can kinda understand that this is a syntax that exists, but in the real world, I say it's used pretty sparingly. I'm sure it's used some places, I haven't used one yet.
[00:08:40]
So it exists, this essentially says, hey, derived class, create a method that does this thing, but it's a static method. So it's not actually part of that, the behavior of an instance of that class, so it's a little odd, but it does exist. There's a couple of big use cases for interfaces.
[00:09:00]
So for a service-based architecture, and in the ASP.NET Core course, when we get to talk about dependency injection, this is gonna become a big topic. It will start to kind of put together why this is important. But service-based architectures that include dependency injection, make interfaces really important to use.
[00:09:22]
They can also be used to mark classes, you can have an empty interface that just simply marks a class as having that interface. Which doesn't sound useful because you're not providing any specific behaviors, you're not providing specific properties. But some frameworks can see that marker and then perform different behaviors on that object downstream based on just the presence of that marker.
[00:09:46]
That's a more of an advanced case, most of the time interfaces are gonna have behaviors and properties that the implementing class is gonna want to implement. But this is a thing that I do and in the ASP.NET Core course, we'll see a sort of example of this. I use interfaces, I don't necessarily think of them as a way to avoid inheritance.
[00:10:13]
But it is a way of kind of providing multiple behaviors to a class without trying to inherit from a class that might have a couple of behaviors and then implement it and then inherit from a class that does the same thing. That also doesn't mean that you want a class that implements ten interfaces.
[00:10:31]
There may be a use for that, but most of my classes are gonna implement no more than one, maybe two, in most of the code that I write. There are some times where there are exceptions. If I want that IEquatable interface where I wanna be able to say, hey, I need to be able to compare this monkey to this human, okay?
[00:10:50]
So I need to implement that interface in order to provide a strongly typed way of doing that, there's reasons to do it. But for the most part, I typically just do an interface to define the contract and then the implementation to actually do the thing. This really also gets into testing, which again, we'll talk about in the ASP.NET Core course cuz testing is a big part of that.
[00:11:14]
>> Student 1: Are there use cases where you'd reach for an abstract class over an interface?
>> Spencer Schneidenbach: Yes, absolutely. Typically, I'm gonna reach for an abstract class when I want to define behaviors for a class. Specifically, when I'm writing ASP.NET Core code, I will have an abstract class that will provide some behavior, some component of ASP.NET Core.
[00:11:38]
And I wanna copy that to all of the derived classes, but do it in a way that kind of reduces code duplication. So absolutely, I use abstract classes frequently, but I use interfaces more. Good question.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops