- C# Programming Cookbook
- Dirk Strauss
- 1400字
- 2021-07-14 11:08:44
Creating and implementing an interface
For many developers, interfaces are confusing and their purpose not clearly understood. Interfaces are actually quite easy to get to grips with once you understand the concept that defines an interface.
Interfaces act like verbs. So, for example, if we had to create two classes called Lion
and Tiger
that derive from the Cat
abstract class, the interface would describe some sort of action. Lions and tigers can roar (but not purr). We can then create an interface called IRoarable
. If we had to derive a class called Cheetah
from our abstract class Cat
, we would not be able to use the IRoarable
interface, because cheetahs purr. We would need to create an IPurrable
interface.
Getting ready
Creating an interface is very similar to creating an abstract class. The difference is that the interface is describing what the class can do, in the case of the Cheetah
class, by implementing IPurrable
.
How to do it…
- If you haven't already done so in the previous recipe, create an abstract class called
Cat
:public abstract class Cat { public abstract void Eat(); public abstract void Hunt(); public abstract void Sleep(); }
- Next, add a class called
Cheetah
that inherits from theCat
abstract class:public class Cheetah : Cat { }
- As soon as you inherit from the
Cat
abstract class, Visual Studio will show you a warning via the lightbulb feature. As you inherited from the abstract classCat
, you have to implement the abstract members within the abstract class in your derived classCheetah
: - This is easily fixable by typing Ctrl +. (period) and fixing all occurrences in the document. You can also do this for the project or solution. For our purpose, we only select the Document link at the bottom of the lightbulb suggestions. Visual Studio will automatically add the abstract methods defined in the abstract class to implement inside your
Cheetah
class: - You will notice that Visual Studio adds just the methods you need to override but will throw
NotImplementedException
if you try to use the class as is. The reason for using an abstract class is to implement the functionality defined in the abstract classCat
in the derived classCheetah
. Not doing so contravenes the rules for using abstract classes:public class Cheetah : Cat { public override void Eat() { throw new NotImplementedException(); } public override void Hunt() { throw new NotImplementedException(); } public override void Sleep() { throw new NotImplementedException(); } }
- To add some implementation, modify your
Cheetah
class as follows. The implementation in the overridden methods is simple, but this validates the rule of writing some sort of implementation in the overridden methods:public class Cheetah : Cat { public override void Eat() { WriteLine($"The cheetah eats."); } public override void Hunt() { WriteLine($"The cheetah hunts."); } public override void Sleep() { WriteLine($"The cheetah sleeps."); } }
Note
You will notice that the following
WriteLine
method is used without theConsole
class. This is because we are using a new feature in C# 6.0 that allows developers to bring static classes into scope by adding theusing static System.Console;
statement to the top of your class file. - Create an interface called
IPurrable
that will be implemented on theCheetah
class. A common naming convention for interfaces dictates that the interface name should be prefixed with a capital I:interface IPurrable { }
- Next, we will add a method to the interface that any class implementing the interface must implement. You will notice that the interface's
SoftPurr
method contains no implementation at all. It however specifies that we will need to pass this method an integer value for the decibel that theCheetah
class will purr at:interface IPurrable { void SoftPurr(int decibel); }
- The next step is to implement the
IPurrable
interface on theCheetah
class. To do this, we need to add theIPurrable
interface name after theCat
abstract class name. If theCheetah
class did not inherit from the abstract class, then the interface name would simply follow after the colon:public class Cheetah : Cat, IPurrable { public override void Eat() { WriteLine($"The cheetah eats."); } public override void Hunt() { WriteLine($"The cheetah hunts."); } public override void Sleep() { WriteLine($"The cheetah sleeps."); } }
- After specifying that the
Cheetah
class implements theIPurrable
interface, Visual Studio once again displays a warning via the lightbulb feature. It is warning us that theCheetah
class does not implement theSoftPurr
method defined in the interfaceIPurrable
: - As we did earlier, we can let Visual Studio suggest possible fixes for the problems encountered by typing Ctrl + . (period). Visual Studio suggests that the interface can be implemented implicitly or explicitly:
- Knowing when to use an implicit or explicit implementation is also quite easy. We first need to know when using one over the other would be preferred. Let's start off by implementing the
SoftPurr
method implicitly by selecting the first option in the lightbulb suggestion. You will see that by selecting to implement theSoftPurr
method defined in theIPurrable
interface implicitly, adds it as if it were part of theCheetah
class:public class Cheetah : Cat, IPurrable { public void SoftPurr(int decibel) { throw new NotImplementedException(); } public override void Eat() { WriteLine($"The cheetah eats."); } public override void Hunt() { WriteLine($"The cheetah hunts."); } public override void Sleep() { WriteLine($"The cheetah sleeps."); } }
- If we look at the
SoftPurr
method, it looks like a normal method inside theCheetah
class. This would be fine unless ourCheetah
class already contains a property calledSoftPurr
. Go ahead and add a property calledSoftPurr
to yourCheetah
class:public class Cheetah : Cat, IPurrable { public int SoftPurr { get; set; } public void SoftPurr(int decibel) { throw new NotImplementedException(); } public override void Eat() { WriteLine($"The cheetah eats."); } public override void Hunt() { WriteLine($"The cheetah hunts."); } public override void Sleep() { WriteLine($"The cheetah sleeps."); } }
- Visual Studio immediately displays a warning by telling us that the
Cheetah
class already contains a definition forSoftPurr
: - It is here that the use of an explicit implementation becomes evident. This specifies that the
SoftPurr
method is a member of the implementation defined in theIPurrable
interface: - Therefore, selecting the second option to implement the interface explicitly will add the
SoftPurr
method to yourCheetah
class as follows:public class Cheetah : Cat, IPurrable { public int SoftPurr { get; set; } void IPurrable.SoftPurr(int decibel) { throw new NotImplementedException(); } public override void Eat() { WriteLine($"The cheetah eats."); } public override void Hunt() { WriteLine($"The cheetah hunts."); } public override void Sleep() { WriteLine($"The cheetah sleeps."); } }
The compiler now knows that this is an interface that is being implemented and is therefore a valid line of code.
- For the purpose of this book, let's just use the implicit implementation. Let's write some implementation for the
SoftPurr
method and use the newnameof
keyword in C# 6.0, as well as the interpolated string for the output. Also, remove theSoftPurr
property added earlier:public void SoftPurr(int decibel) { WriteLine($"The {nameof(Cheetah)} purrs at {decibel} decibels."); }
- Heading over to our console application, we can call our
Cheetah
class as follows:Cheetah cheetah = new Cheetah(); cheetah.Hunt(); cheetah.Eat(); cheetah.Sleep(); cheetah.SoftPurr(60); Console.ReadLine();
- Running the application will produce the following output:
How it works…
So, you might be wondering what the difference between an abstract class and an interface is. It basically comes down to where you want your implementation. If you need to share functionality between derived classes, then an abstract class is the best fit for your needs. In other words, we had specific things that were common to all cats (lions, tigers, and cheetahs) such as hunting, eating, and sleeping. This is then best used within an abstract class.
If your implementation is specific to a class or several classes (but not all classes), then your best course of action would be to use an interface. In this case, the IPurrable
interface can be applied to several classes (for example, cheetahs and domestic cats) but can't be applied to all cats (such as lions and tigers), because not all cats can purr.
Knowing this difference and where you need to place your implementation will aid you in deciding whether you need to use an abstract class or an interface.
- Vue 3移動Web開發與性能調優實戰
- Visual FoxPro程序設計教程
- JMeter 性能測試實戰(第2版)
- BeagleBone Media Center
- Java設計模式及實踐
- H5頁面設計:Mugeda版(微課版)
- Unity Game Development Scripting
- 區塊鏈技術進階與實戰(第2版)
- OpenCV with Python By Example
- 區塊鏈架構之美:從比特幣、以太坊、超級賬本看區塊鏈架構設計
- 遠方:兩位持續創業者的點滴思考
- Node.js區塊鏈開發
- 超簡單:Photoshop+JavaScript+Python智能修圖與圖像自動化處理
- Python Programming for Arduino
- Selenium WebDriver Practical Guide