Hello to all!

In continuation of the topic Link to a class or delegate , where the distinguished @Alex Krass tried to explain to me the benefits of using the interface.

For me, everything remains a mystery. I still think that this is an extra scribbling code. During this time, I read a lot of articles about the interface and watched the video course. But I did not understand. Honestly, I do not know why I was fixated on him, because I would not know about its existence, I would have finished writing my project a long time ago.

Here, for example, Alex explains that in his example, he can easily add another 100 useConnect classes, but, in my opinion, he also needs to call connect = new UseConnect(ссылка на класс()); 100 times connect = new UseConnect(ссылка на класс()); , and in his particular case he will have to produce a switch to call all the classes. And I did not understand how in this case you can get to the method from any class, in that example, you can call them all in a heap. And if in the main class I need to use some method again, then I will again have to rewrite connect = new UseConnect(ссылка на класс()); . In my case, where I simply write a reference to a class and call a method through a variable, I can use this variable whenever I want and when I want, and I can call any of the methods. And in general, I don’t have to write the UseConnect class, I can call methods right away, in this example from the MySQL class, for example.

Here is a real example that I need to implement in my example. Again, I repeat, with the help of the reference to the classes I have already solved this problem. I just want to see how the pros do this with the help of interfaces.

Here is an example. I have a form in which the user can save records in the database. In my case, MySQL. He can make a record, then call it and make changes. I have five classes. The main one, which calls the form, class, class, class, class, class, and class of connection to the database. The insertd up and select class inherit the database connection class. Well, I decided to do this in order not to use the interface. Here is the task: how can I connect these four classes with the interface (s) to the main class with the form.

Well, I took it for my example. Better, of course, give an explicit example where the interface makes life easier for the programmer. Please do not start the topic of my literacy and knowledge of the Russian language. We have already discussed this topic and more than once I spoke about the reason for my illiteracy in the Russian language. And just do not send me for a book, well, if you only advise a good one.

  • The interface is primarily interesting for interclass interaction. For example, if you don’t go far, there is a standard interface (ISortable) And there is a standard class that sorts ISortable objects (I don’t remember which one). Without interfaces, you could not use this class to sort your collections, and you would have to implement your sorting method. And so, you implement only the necessary methods in your class, and use the whole range of auxiliary classes for operations on them. And this is just the tip of the iceberg. - Chad
  • @Chad I understand everything perfectly, people came up with C # 1000 times smarter than me. And, of course, the interface is needed. But how they work, it never reaches me, in terms of what I do not understand where his superiority is. After all, for me it is even more scribbling code, and if I need to add a class, then I still need to kill, for example, the main class. In the end, we also create a reference to the class and call methods. Jac where is the point? - Gennady Pisarev
  • @Gennadiy Pisarev, you are clearly hanging around in one place. I do not even know what other words to explain it to you. For now, it’s better to forget about the interfaces, and then, in the course of professional development, you can then understand their advantage empirically. - DreamChild
  • @DreamChild Thanks for the tip. I also thought about it. But still I would like to understand the initial stage of its development, because there are still delegates ahead. :) - Gennady Pisarev
  • I don’t know what you have there, Sharpista, and in my case everything is simple in Java - I declared the List <Animal> collection and store in it objects not of the class but of the interface. 1. Cat implements Animal 2. Dog implements Animal 3. Rabbit implements Animal But otherwise these animals cannot be stuffed into the collection !! - arg

1 answer 1

Now you most likely do not need it, you will come up with it sometime later, when you are ready. Do not bother and go further, very often programmers are forced to skip topics and return to them. The main thing is that you know that there is such a thing as an interface, and it allows you to hide real implementations of classes.

With the help of interfaces you:

  • Do not tie the logic of your application with specific classes and you can easily make changes to one class, without touching others, adding functionality or replacing one class with another, without touching the whole application. That is, an abstraction from the implementation is implemented;
  • you can design the application logic on the interfaces, leaving the implementation for later and using the stubs;
  • apply the so-called multiple inheritance;
  • if you are a boss, you can easily convey your thoughts to subordinates (implement me the functionality of this interface here).

I will give a few examples in which the interface is used, but at once I make a reservation, they are not the best representatives. After all, I am also studying. )

Design of a non-zoo

Let's design a small program of the zoo, while the zoo we will step by step.

1. First of all, it is worth populating animals that can walk on it, let's get started.

To describe the zoo life cycle, I use the ZooLivecycle class:

  class ZooLivecycle { public void allPetWalk() { } } 

So, we have animals that can walk, let's define their capabilities through interfaces and implement them.

 interface IWalk { void walk(); } class Cat : IWalk { public void walk() { Console.WriteLine("cat walk"); } } class Dog : IWalk { public void walk() { Console.WriteLine("dog walk"); } } class Fish : IWalk { public void walk() { Console.WriteLine("fish cant walk"); } } class Bird : IWalk { public void walk() { Console.WriteLine("bird can fly"); } } 

In order for all animals to go, it is easier to transfer them to the zoo class by the whole array and walk through them in a cycle.

 class ZooLivecycle { public void allPetWalk(IWalk[] arr) { for (int i = 0; i < arr.Count(); i++) arr[i].walk(); } } 

So now we can call our implementation.

 class Program { static void Main(string[] args) { ZooLivecycle zoo = new ZooLivecycle(); IWalk[] walks = new IWalk[]{new Cat(), new Dog(), new Fish(), new Bird()}; Console.WriteLine("\n*Pet Walk*"); zoo.allPetWalk(walks); Console.Read(); } } 

And now try to implement it without interfaces, mainly the allPetWalk function, although there is a way - this is a common parent class. You can also try to pass the link as public void allPetWalk(Object[] arr) and then public void allPetWalk(Object[] arr) types, but this is a very bad practice, since you lose control over the types and have to add checks that are not the best solution.

2. Go ahead, we decided to add a surveillance system, namely a video camera that can transmit information.

 interface IObservation { void analyze(); } class Videocamera : IObservation { public void analyze() { Console.WriteLine("In zoo all ok"); } } 

We sell information in the zoo classroom:

 class ZooLivecycle { public void allPetWalk(IWalk[] arr) { for (int i = 0; i < arr.Count(); i++) arr[i].walk(); } public void zooAnalyze(IObservation[] arr) { for (int i = 0; i < arr.Count(); i++) arr[i].analyze(); } } 

Well, the challenge.

 class Program { static void Main(string[] args) { ZooLivecycle zoo = new ZooLivecycle(); IWalk[] walks = new IWalk[]{new Cat(), new Dog(), new Fish(), new Bird()}; IObservation[] analyze = new IObservation[] { new Videocamera() }; Console.WriteLine("\n*Pet Walk*"); zoo.allPetWalk(walks); Console.WriteLine("\n*Analyze zoo*"); zoo.zooAnalyze(analyze); Console.Read(); } } 

3. And now let's poddle a pig if someone still used the parent class instead of interfaces.

We implement an assistant who can both walk around the zoo and transmit information. In C #, there is no cross-inheritance, but you can inherit multiple interfaces instead.

 class HelperPet : IWalk, IObservation { public void walk() { Console.WriteLine("helppet walk"); } public void analyze() { Console.WriteLine("helppet analyze"); } } 

That's all I had to add. You can continue to use our zoo, without rewriting anything.

 class Program { static void Main(string[] args) { ZooLivecycle zoo = new ZooLivecycle(); IWalk[] walks = new IWalk[]{new Cat(), new Dog(), new Fish(), new Bird(), new HelperPet()}; IObservation[] analyze = new IObservation[] { new Videocamera(), new HelperPet() }; Console.WriteLine("\n*Pet Walk*"); zoo.allPetWalk(walks); Console.WriteLine("\n*Analyze zoo*"); zoo.zooAnalyze(analyze); Console.Read(); } } 

Now let's look at real-life examples that are very often used.

Very often, interfaces are used as descriptive models, the inheritance from which makes it possible to work with what they are created for. Thus, you are not tied to specific classes. In the language itself, C # even has interfaces that implement this or that behavior. You will often encounter this if you go to a WPF or ASP.NET MVC application.

Using foreach with own classes

Let's improve our zoo and add an animal storage class. Despite the fact that it is rather voluminous, I just took an example from MSDN and just substituted my values.

  public interface IWalk { void walk(); } public class Animals : IEnumerable<IWalk> { private IWalk[] _pets; public Animals(IWalk[] pArray) { _pets = new IWalk[pArray.Length]; for (int i = 0; i < pArray.Length; i++) { _pets[i] = pArray[i]; } } IEnumerator IEnumerable.GetEnumerator() { return (IEnumerator)GetEnumerator(); } public PetsEnum GetEnumerator() { return new PetsEnum(_pets); } IEnumerator<IWalk> IEnumerable<IWalk>.GetEnumerator() { return (IEnumerator<IWalk>)GetEnumerator(); } } public class PetsEnum : IEnumerator { public IWalk[] _pets; int position = -1; public PetsEnum(IWalk[] list) { _pets = list; } public bool MoveNext() { position++; return (position < _pets.Length); } public void Reset() { position = -1; } object IEnumerator.Current { get { return Current; } } public IWalk Current { get { try { return _pets[position]; } catch (IndexOutOfRangeException) { throw new InvalidOperationException(); } } } } Теперь я могу делать так: class Program { static void Main(string[] args) { ZooLivecycle zoo = new ZooLivecycle(); Animals animals = new Animals(new IWalk[]{new Cat(), new Dog(), new Fish(), new Bird(), new HelperPet()}); Console.WriteLine("\n*Pet Walk*"); zoo.allPetWalk(animals); Console.Read(); } } class ZooLivecycle { public void allPetWalk(Animals animals) { foreach(IWalk animal in animals) animal.walk(); } } 

Without implementing the interface, you cannot use foreach with your class, although in fact it is done very quickly. In this case, the foreach method works with any objects, and if there were no interfaces, it would be more difficult to achieve this effect. Now you can add methods such as Add, Remove, etc. to the Animals class.

Well, in the end, you can put the stub and transfer test data.

If the implementation of classes is quite complicated, for example, one of them receives data from the database, and the other processes this data, then you can write a fake class. That is, instead of real data, you transfer a class that does not use a connection to the database, and then it can be rewritten. Moreover, it is possible to work normally both with one and with another class alternately.