Абстрактные методы и классы
Иногда полезно создать базовый класс, определяющий только своего рода "пустой бланк", который унаследуют все производные классы, причем каждый из них заполнит этот "бланк" собственной информацией. Такой класс определяет структуру методов, которые производные классы должны реализовать, но сам при этом не обеспечивает реализации этих методов. Подобная ситуация может возникнуть, когда базовый класс попросту не в состоянии реализовать метод. В данной ситуации разрабатываются абстрактные методы или целые абстрактные классы.
Абстрактный метод создается с помощью модификатора abstract. Он не имеет тела и, следовательно, не реализуется базовым классом, а производные классы должны его обязательно переопределить. Абстрактный метод автоматически является виртуальным, однако использовать спецификатор virtual не нужно. Более того, если вы попытаетесь использовать два спецификатора одновременно, abstract и virtual, то компилятор выдаст сообщение об ошибке.
Если класс содержит один или несколько абстрактных классов, то его также нужно объявить как абстрактный, используя спецификатор abstract перед class. Поскольку абстрактный класс полностью не реализован, то невозможно создать экземпляр класса с помощью операции new. Например, если класс Demo определен как абстрактный, то попытка создать экземпляр класса Demo повлечет ошибку:
Demo a = new Demo();
Однако, можно создать массив ссылок, используя этот же абстрактный класс:
Demo [] Ob=new Demo[5];
Если производный класс наследует абстрактный, то он должен полностью переопределить все абстрактные методы базового класса или также быть объявлен как абстрактный. Таким образом, спецификатор abstract наследуется до тех пор, пока в производном классе не будут реализованы все абстрактные методы.
Рассмотрим пример использования абстрактных методов и классов.
abstract class Demo //абстрактный класс
{
abstract public void Show();//абстрактный метод
abstract public double Dlina();//абстрактный метод
}
class DemoPoint:Demo //производный класс от абстрактного
{
protected int x;
protected int y;
public DemoPoint (int x, int y)
{
this.x=x; this.y=y;
}
public override void Show() //переопределение абстрактного метода
{ Console.WriteLine("точка на плоскости: ({0}, {1})",x, y); }
public override double Dlina() //переопределение абстрактного метода
{
return Math.Sqrt(x*x+y*y);
}
}
class DemoShape : DemoPoint //производный класс
{
protected int z;
public DemoShape(int x, int y, int z):base(x, y)
{ this.z=z; }
public override void Show() //переопределение абстрактного метода
{ Console.WriteLine("точка в пространстве: ({0}, {1}, {2})", x, y, z); }
public override double Dlina() //переопределение абстрактного метода
{ return Math.Sqrt(x*x+y*y+z*z); }
}
class DemoLine : DemoPoint //производный класс
{
protected int x2;
protected int y2;
public DemoLine(int x1, int y1, int x2, int y2):base(x1, y1)
{ this.x2 = x2; this.y2 = y2; }
public override void Show() //переопределение абстрактного метода
{
Console.WriteLine("отрезок на плоскости: ({0}, {1})-({2},{3})",x,y, x2, y2);
}
public override double Dlina() //переопределение абстрактного метода
{ return Math.Sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2)); }
}
class Program
{
static void Main()
{
Demo [] Ob=new Demo[5]; //массив ссылок
//заполнения массива ссылками на объекты производных классов
Ob[0]=new DemoPoint(1,1);
Ob[1]=new DemoShape(1,1,1);
Ob[2]=new DemoLine(0,3,4,0);
Ob[3]=new DemoLine(2,1,2,10);
Ob[4]=new DemoPoint(0,100);
foreach (Demo a in Ob) //просмотр массива
{
a.Show();
Console.WriteLine("Dlina: {0:f2}\n", a.Dlina());
}
}
}
Контрольные вопросы:
1.Понятие и синтаксис множественного наследования.
2.Особенности множественного наследования.
3.Достоинства и недостатки множественного наследования.
4.Многократное наследование.
5.Виртуальные базовые классы.
6.Множественное наследование в .NET.
7.Для каких целей применяется наследование?
Дата добавления: 2015-10-26; просмотров: 2078;