Lecture thumbnail 0:00 / 0:00 The whole saga of multiple inheritance got an additional twist with the release of C sharp eight because

now we have something called default interface members.

Now, from the perspective of the end user default interface members and extension methods have almost

identical mechanics.

And in actual fact, one could argue that extension methods are better because they don’t have to be

specified in the inheritance list of a particular type.

But we can do the dragon scenario using default interface implementations and I want to show you how

it’s done and what are the caveats, because obviously we don’t have multiple inheritance in C sharp.

We are probably never going to get it.

But having default interface members allows us to effectively try to build a kind of decorator using

behavior which is placed directly into interfaces as opposed to into extension methods or indeed classes

which wrap the class you’re working with.

So let’s imagine you have an interface creature.

So we have an eye creature and here we’ll only have the age.

So we have the age property here and then we’ll have an interface called Eye bird, Eye bird, which

is an eye creature.

So here we’ll have a method called fly and the creature is going to fly assuming it’s older than ten.

So if age is greater than or equal to ten, we’re going to have writeline.

I am flying.

So that’s the implementation of the eye bird interface with a default definition of the fly method.

So assuming you don’t change the definition of fly, when you come to implement the actual type that

you want to work with, this is the method that’s going to be called and we can do the same for Eye

Lizard.

Public Interface.

Eye lizard, which is going to be an eye creature.

And once again, we’ll have a method this time around called Crawl.

So here we say, if age is less than ten then Writeline I am crawling.

Okay, so you can think of both eye bird and eye lizard as ways of extending some creature types.

So for example, if you have a dragon, then you can say, Well, let’s actually let’s not do it this

way.

Let’s imagine that you have a dragon which has a public int age get and set.

Imagine that this is your starting point.

So your starting point is a dragon.

Its interface conforms to eye creature.

Maybe you even define it like this.

Maybe you even define it like creature.

And what you do is you decide to add additional behaviors to dragon, but you decide that you want to

add them on the side.

So what are your options If you want to add additional behaviors on the side, obviously you have well,

you have really several different options.

So one is inheritance.

So assuming you can afford to inherit from Dragon, you can do that.

You can totally do that.

But imagine that’s not an option.

Imagine that a dragon inherits from some.

I don’t know.

Actually.

They’re not mammals, are they?

They lay eggs.

I think so.

So public class organism, that’s a fancy word.

So we have an organism and so the dragon inherits from organism.

So you don’t have an ability to inherit from yet another class because obviously we don’t have multiple

inheritance.

So what are your options then, If you want to add additional storage, like additional fields, for

example, then your option is a wrapper kind of decorator.

So you would have maybe small dragon, which would be a class which wraps dragon.

So that’s, that’s the typical implementation of the decorator design pattern.

However, if you just want to add behavior, you have two different options.

So the first option is extension methods.

So you add behavior to to the Dragon class.

And the second option is the C-sharp eight default interface methods.

And that’s exactly what we’re going to take a look at here.

So you decide that you want to add this eye, bird and eye lizard behavior to the dragon after the fact.

So you already have a dragon.

It’s an organism and it has this eye creature.

Now what you can do is you can also put eye, bird and eye lizard here.

Now, strictly speaking, another thing you can do is you can delete eye creature because bird and eye

lizard are both inheriting from eye creature.

So you can delete our creature.

You can leave eye creature here if you want to.

It doesn’t really matter because what you’re doing is intrusive anyway.

What you’re doing is changing the dragon class, whatever you do, basically.

So it’s still going to go down like this.

And then we can we can start working with the dragon.

And I’ll show you how you can get all this additional behavior.

So obviously.

So if we make a dragon.

So let’s just make a dragon.

One thing you should realize is you don’t have methods like fly or crawl on the dragon.

So.

So the type of the variable here, let’s just explicitly specify the type.

The type is dragon.

Dragon does not have either fly or crawl, so it’s not multiple inheritance in the sense of, you know,

typical V table stuff.

Instead, you do have implementations of bird and lizard, but they are special.

And the reason why they are special is because they have default members.

As soon as an interface has a default member.

Your your.

Well, essentially you no longer have the the members of this interface available right on the type.

So with ordinary types, like with creature, for example, you have age.

So if I were to take Dragon, I can say dot age.

Well, like I do here, I can access age directly.

I’m accessing this age.

But this actually refers to this property right here inside creature.

So there is no problem with I creature because it doesn’t have any default implementations but high

bird and I lizard do, which means that if you want to actually access them, you have to perform casts.

So either you cast a dragon.

So you say, oh, let’s cast dragon to an I lizard so you can cast the dragon, and then you have the

curl method.

So this is one possibility, or you can do it using these wonderful smart casts in C sharp.

So you can say if the is a bird bird, then butterfly.

And similarly, you can say if the is lizard, lizard, then lizard dot crawl, something like that.

So that’s another possibility that’s available to you.

And obviously if you want to have additional behaviors, what you would have to do is you would have

to make a new interface, kind of like the lizard interface, maybe inherit from my creature, maybe

not.

If you need the age variable, then certainly to access this property you do need to inherit from creature

because if you don’t, then suddenly this part becomes invalid.

Because where does the age come from exactly?

So after you implement this interface, you have to basically break the open closed principle and jump

into Dragon and add another inherited to the list.

So it’s it’s more intrusive than using extension methods because when you add an extension method to

a class, you don’t modify the class itself, whereas here you do.

So this is another approach that you can take to actually have have the behaviors sort of added on and

being kept in a separate type, in this case a separate interface, and then just just having access

to that interface.

But it’s a lot less intuitive because now what you have to do is you have to perform these casts.

So without these casts, unfortunately, nothing is going to work.

Play Play Play Play Stop Play Play Play Play Start Play information alert