MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Moștenirea interfețelor

Interfețele, la fel ca și clasele, pot fi moștenite:

interface IAction
{
   void Move();
}
interface IRunAction : IAction
{
   void Run();
}
class BaseAction : IRunAction
{
   public void Move()
   {
       Console.WriteLine("Move");
   }
   public void Run()
   {
       Console.WriteLine("Run");
   }
}

La aplicarea acestui interfaței, clasa BaseAction trebuie să implementeze atât metodele și proprietățile interfeței IRunAction, cât și metodele și proprietățile interfeței de bază IAction, dacă aceste metode și proprietăți nu au o implementare implicită.

Totuși, spre deosebire de clase, nu putem aplica interfețelor modificatorul sealed pentru a interzice moștenirea acestora.

De asemenea, nu putem aplica interfețelor modificatorul abstract, deoarece interfața, în general, oferă un funcțional abstract care trebuie să fie implementat într-o clasă sau structură (cu excepția metodelor și proprietăților cu implementare implicită).

Totuși, metodele interfețelor pot utiliza cuvântul cheie new pentru a ascunde metodele din interfața de bază:

IAction action1 = new RunAction();
action1.Move(); // I am moving

IRunAction action2 = new RunAction();
action2.Move(); // I am running

interface IAction
{
   void Move() => Console.WriteLine("I am moving");
}
interface IRunAction : IAction
{
   // ascundem implementarea din IAction
   new void Move() => Console.WriteLine("I am running");
}
class RunAction : IRunAction { }

Aici, metoda Move din IRunAction ascunde metoda Move din interfața de bază IAction. Aceasta are sens dacă în interfața de bază este definită o implementare implicită, care trebuie suprascrisă. În cazul de mai sus, dacă variabila reprezintă tipul IRunAction, pentru metoda Move se va apela implementarea acestui interfeței:

IRunAction action2 = new RunAction();
action2.Move(); // I am running

În caz contrar, dacă variabila reprezintă tipul IAction, pentru metoda Move se va aplica implementarea acestei interfeței:

IAction action1 = new RunAction();
action1.Move(); // I am moving

Dar clasa RunAction poate suprascrie metoda Move pentru ambele interfețe.

IAction action1 = new RunAction();
action1.Move(); // I am tired

IRunAction action2 = new RunAction();
action2.Move(); // I am tired

interface IAction
{
   void Move() => Console.WriteLine("I am moving");
}
interface IRunAction : IAction
{
   new void Move() => Console.WriteLine("I am running");
}
class RunAction : IRunAction
{
   public void Move() => Console.WriteLine("I am tired");
}

La moștenirea interfețelor, trebuie să avem în vedere că, la fel ca și în cazul moștenirii claselor, interfața derivată trebuie să aibă același nivel de acces sau unul mai restrictiv decât interfața de bază. De exemplu:

public interface IAction
{
   void Move();
}
internal interface IRunAction : IAction
{
   void Run();
}

Dar nu invers. De exemplu, în următorul caz vom primi o eroare și programul nu va fi compilat, deoarece interfața derivată are un nivel de acces mai puțin restrictiv decât interfața de bază:

internal interface IAction
{
   void Move();
}
public interface IRunAction : IAction   // eroare IRunAction poate fi doar internal
{
   void Run();
}
← Lecția anterioară Lecția următoare →