Кратко съдържание



страница30/73
Дата21.07.2018
Размер8.57 Mb.
1   ...   26   27   28   29   30   31   32   33   ...   73

Абстрактни класове


Абстрактните класове приличат на интерфейсите по това, че те не могат да се инстанцират, защото могат да съдържат дефиниции на неимплемен­тирани методи, но за разлика от интерфейсите могат да съдържат и описани дей­ствия. Абстрактният клас реално е комбинация между клас и интерфейс – частично имплемен­тиран клас, който дефинира имплемен­тация за някои от методите си, а други оставя абстрактни, без импле­ментация.

За пример нека разгледаме следния абстрактен клас:



AbstractTest.cs

public abstract class Car

{

public void Move()



{

// Move the car

}
abstract public int TopSpeed

{

// Retrieve the top speed in Kmph



get;

}

public abstract string BrandName



{

get;


}

}


Дефинирахме клас, който реализира само един от членовете си – метода Move() и дефинира други два, без да ги реализира – свойствата BrandName и TopSpeed.

Абстрактните класове, подобно на интерфейсите, ни помагат по-адекватно да моделираме зависимости от реалният свят, защото чрез тях могат да се представят абстрактни същности. В нашия пример невъзможността за инстанциране на класа Car има смисъл, тъй като и в реалността не можем да имаме кола с неопределена марка.


Абстрактни членове


Ключовата дума abstract в декларацията на класа го определя като абстрактен. Виждаме, че тя може да се приложи и към член. Абстрактни могат да бъдат методите, свойствата, индексаторите и събитията.



Абстрактните членове не могат да имат имплементация, както и член, който не е абстрактен, не може да бъде оставен без такава.

Ако в един клас е дефиниран абстрактен член, класът задължително трябва да бъде обявен за абстрактен. В противен случай получаваме грешка при компилация. Обратното не е задължително – допустимо е да имаме абстрактен клас, на който всички членове са дефинирани.

Наследяване на абстрактни класове


Тъй като абстрактните класове са класове, те имат същата структура - същият набор от членове (полета, константи, вложени типове и т. н.), същите модификатори на видимостта и дори същите механизми за насле­дяване, но с някои особености. Нека разширим предходния пример:

AbstractTest.cs

public class Trabant : Car

{

public override int TopSpeed



{

get


{

return 120;

}

}
public override string BrandName



{

get


{

return "Trabant";

}

}

}


public class Porsche : Car

{

public override int TopSpeed



{

get


{

return 250;

}

}
public override string BrandName



{

get


{

return "Porsche";

}

}

}


public class AbstractTest

{

static void Main()



{

Car[] cars = new Car[] {new Trabant(), new Porsche()};

foreach (Car car in cars)

{

Console.WriteLine("A {0} can go {1} Kmph",



car.BrandName, car.TopSpeed);

}

}



}

При изпълнението на този код получаваме следния резултат:

A Trabant can go 120 Kmph

A Porsche can go 250 Kmph

Виждаме, че въпреки че абстрактният клас не може да се инстанцира директно, обектите от наследяващите го класове могат да се разглеждат като обекти от неговия тип. По показания начин можем да използваме абстрактни базови класове, за да задействаме полиморфизъм, или, казано по-общо, да създадем абстрактен корен на дърво от класове.

В примера ползвахме ключовата дума override, с която указваме, че даден метод в класа наследник припокрива (замества) оригиналния наследен метод от базовия си клас. В случая базовия клас не предоставя имплементация за припокритите методи, така че припокриването е задължително. Ще разгледаме ключовата дума override и нейното действие след малко. Нека сега продължим с абстрактните класове.


Частично реализиране на абстрактните членове


Възможно е абстрактен клас, съдържащ абстрактни членове, да бъде наследен, без всичките му абстрактни членове да бъдат реализирани. Възможно е също клас, който имплементира абстрактните членове на абстрактния си родител, да дефинира допълнително и свои членове, също абстрактни. В този случай класът-наследник също трябва да бъде декла­риран като абстрактен, защото съдържа абстрактни членове.

Тези възможности правят още по-гъв­кав инструментариума за създаване на йерархии от класове и мо­де­ли­ра­не на реалния свят. Ще илюстрираме тази възможност със следното разширение на предходния пример:



AbstractTest.cs

abstract public class TurboCar : Car

{

protected Boolean mTurboEnabled = false;



public void EnableTurbo()

{

mTurboEnabled = true;



}

public void DisableTurbo()

{

mTurboEnabled = false;



}

}
public class TrabantTurbo : TurboCar

{

override public int TopSpeed



{

get


{

return mTurboEnabled ? 220 : 120;

}

}
override public string BrandName



{

get


{

return "Trabant Turbo";

}

}

}


public class AbstractTest

{

static void Main()



{

TurboCar turboCar = new TrabantTurbo();

Console.WriteLine("A {0} can go {1} Kmph",

turboCar.BrandName, turboCar.TopSpeed);


turboCar.EnableTurbo();

Console.WriteLine(

"A {0} can go {1} Kmph with turbo enabled",

turboCar.BrandName, turboCar.TopSpeed);

}

}


Създадохме класа TrabantTurbo, който реализира абстрактните свойства, индиректно наследени от класа TurboCar. Класът TurboCar е разширение на класа Car, който също като него е абстрактен, но предоставя допълни­телна функционалност за включване на режим "турбо".



Ако един клас наследи от абстрактен и не предостави дефиниции за всички негови абстрактни членове, той трябва задължително също да бъде обявен за абстрактен.

След изпълнени­ето на примера по­лу­ча­ва­ме следния резултат:

A Trabant Turbo can go 120 Kmph

A Trabant Turbo can go 220 Kmph with turbo enabled

1   ...   26   27   28   29   30   31   32   33   ...   73


База данных защищена авторским правом ©obuch.info 2016
отнасят до администрацията

    Начална страница