Nasleđivanje je jedan od osnovnih koncepata objektno orijentisanog programiranja. Klasa koja je izvedena iz osnovne klase nasleđuje sve atribute i metode te klase. Za osnovnu klasu se u literaturi često sreće i naziv bazna klasa, natklasa ili superklasa. Često korišćeni termin za izvedenu klasu je podklasa. U programskom jeziku C# izvedena klasa može da nasledi samo jednu baznu klasu. Koncept višestrukog nasleđivanja prisutan u jeziku C++ je izbačen. Da bi se neka klasa definisala kao izvedena klasa neke druge klase koristi se operator: ("dve tačke"). Oznaka public class B : A označava da je klasa B izvedena iz klase A. Posle ovakve oznake dolazi definicija tela klase izvedene klase B unutar litičastih zagrada. U nekim situacijama će korisnik želeti da zabrani nasleđivanje svoje klase. To se postiže korišćenjem ključne reči sealed. Klasa koja u svojoj definiciji ima reč sealed ne može se naslediti.
Da bi se ilustrovao koncept nasleđivanja u nastavku je definisana klasa A koja će se kasnije iskoristiti kao bazna klasa. Radi ilustracije prava pristupa i uticaja na nasleđivanje, u klasi su definisana 3 atributa od kojih je jedan public, drugi private, a treći protected. U konstruktoru klase se ovi atributi označeni sa a1, a2 i a3 inicijalizuju na vrednosti 1, 2 i 3 respektivno. Klasa ima metodu stampajA() koja služi za štampanje vrednosti svojih atributa.
public class A
{
public int a1;
private int a2;
protected int a3;public A()
{
a1 = 1;
a2 = 2 ;
a3 = 3;
}public void stampajA()
{
Console.WriteLine("Vrednosti a1 a2 i a3 su {0} {1} {2}",a1,a2,a3);
}
}
U primeru je realizovana klasa B koja je izvedena iz klase A. Klasa B pored atributa a1, a2 i a3 koje je nasledila od klase A uvodi još jedan dodatni atribut označen sa b. Konstruktor klase B inicijalizuje atribut b na vrednost 100. Prilikom konstruisanja objekta izvedene klase ukoliko se eksplicitno ne naznači najpre se poziva podrazumevani konstruktor bazne klase a tek onda pozvani konstruktor izvedene klase. Objekat klase B označen sa objB je nasledio atribute a1, a2 i a3 bazne klase kao i metodu stampajA. Iako je objekat B nasledio atribut a2 unutar klase B ne može da mu se pristupi korišćenjem operatora . ("tačka"). To je zbog činjenice da je atribut a2 privatan. Atributu a1 se može pristupiti preko operatora . ("tačka") jer je javan. Vrednost atributa a1 se može pročitati korišćenjem javne metode stampajA koju je objekat objB nasledio. Takođe se može pristupiti i atributu a3 jer je protected, a kao što je poznato protected atribut se za članove izvedene klase ponaša kao public.
public class B : A
{
public int b ;
public B()
{
b= 100;
}
[STAThread]static void Main(string[] args)
{
B objB = new B();
// objB je nasledio a1,a2 i a3
Console.WriteLine("Pre setovanja vrednosti su : " );
objB.stampajA();
objB.a1 = 11;
objB.a2 = 13;
Console.WriteLine("Posle setovanja vrednosti su : " );
objB.stampajB();
Console.ReadLine();
}
}
U primeru je definisana i metoda stampajB karakteristična samo za izvedenu klasu. Unutar izvedene metode moguće je pozvati metodu osnovne klase korišćenjem ključne reči base, npr. base.stampajA().
public void stampajB()
{
// mogu da pozovem funkciju osnovne klase
base.stampajA();
Console.WriteLine(" \n Vrednost b je {0} ",b);
}
Poziv baznog konstruktora iz izvedene klase
Kao što je rečeno prilikom konstruisanja objekta izvedene klase se najpre poziva podrazumevani konstruktor bazne klase. Postavlja se pitanje kako pozvati neki drugi konstruktor bazne klase ukoliko bazna klasa pored podrazumevanog ima i parametarske konstruktore. Neka bazna klasa označena sa A ima parametarski konstruktor definisan izrazom public A(int novoA){... telo konstruktora} . Da bi se pozvao ovaj konstruktor klase A potrebno je prilikom deklarisanja konstruktora klase B napisati :
public B (int nekoA, int nekoB): base(nekoA){... telo konstruktora klase B}.
Izvedena klasa nasleđuje metode bazne klase. Postoje situacije u kojima se želi da se u izvedenoj klasi prebriše metoda bazne klase i umesto nje definiše metoda sa istim potpisom ali različitim telom metode. Kada se kreira metoda bazne klase za koju se očekuje da će biti prebrisana u izvedenoj klasi metoda se označava kao virtuelna korišćenjem službene reči virtual. Metod u izvedenoj klasi koji ima isto ime kao i virtuelni metod u baznoj klasi vrši "prebrisavanje" (override) metoda iz bazne klase.
Pisanje virtuelnih metoda
U nastavku je dat primer definisanja jednostavne virtuelne metode u baznoj klasi kao i prikazan postupak njenog overriding-a u izvedenoj klasi.
Metoda osnovne klase:
public virtual void stampaj()
{
Console.WriteLine("Metoda osnovne klase");
}
metoda izvedene klase:
public override void stampaj()
{
Console.WriteLine(" Metoda izvedene klase");
}
Sad kada objekat bazne klase pozove metodu stampaj() poziva se metoda bazne klase, a kada objekat izvedene klase pozove tu istu metodu poziva se metoda stampaj iz izvedene klase.
Apstraktna metoda je prazna metoda tj. metoda koja nema implementaciju. Apstraktna metoda dakle nema telo, nema ni prazno telo. Klasa koja ima bar jednu apstraktnu metodu naziva se apstraktna klasa. Da bi se metoda ili klasa označila kao apstraktna koristi se ključna reč abstract. Apstaktna klasa može imati metode koje nisu apstraktne. Apstraktna klasa ne može da se instancira. Klasa koja je izvedena iz apstraktne klase mora da realizuje (implementira) sve apstraktne metodee tj. da definiše njihovo telo.
Nasleđivanje apstraktne metode
U nastavku je prikazana apstraktna klasa A koja pored ostalih članova ima apstraktnu metodu prikazi. Iz klase A je izvedena klasa B. Sada klasa B mora da realizuje apstraktnu metodu nasleđenu iz klase A. Radi ilustracije u telu metode prikazi vrši se prikazivanje teksta na standardnom izlazu.
public abstract class A
{
...
// apstraktna metoda
public abstract void prikazi();
}
...
public class B : A
{
...
// realizacija metode apstraktne klase
public override void prikazi()
{
Conslole.WriteLine("Realizacija");
}
Interfejs je koncept koji razdvaja specifikaciju metoda od njegove implementacije. U interfejsu se vrši samo deklaracija a ne i definicija metoda. Za definisanje interfejsa koristi se službena reč interface. Interfejs ne može da se instancira. Klasa može da nasledi tj. implementira više interfejsa. Metoda u klasi koja implementira metodu iz interfejsa mora biti javna. Interfejs može da nasledi više interfejsa.
Definisanje interfejsa
Dat je primer definisanja interfejsa. U interfejsu su date deklaracije metoda napuni i prikazi. Uobičajeno je da ime interfejsa počinje velikim slovom I.
interface IOsoba
{
void Napuni(string MLB1,string ImePrezime1,string Adresa1, string BrojIndeksa1, int Godina1);
void Prikazi();
}
Implementiranje interfejsa
U nastavku je prikazana klasa Student koja implementira interfejs IOsoba definisan u prethodnom primeru. U klasi se moraju definisati dve javne metode napuni i prikazi koje realizuju metode iz interfejsa.
public class Student : IOsoba
{
...
public void Napuni(string MLB1,string ImePrezime1,string Adresa1, string BrojIndeksa1, int Godina1)
{
... realizacija metode
}public void Prikazi()
{
... realizacija metode
}
...
}