- •Иерархия классов
- •Наследование
- •Использование защищенного доступа
- •Наследование конструкторов
- •1) Позволяет вызвать конструктор базового класса:
- •2) Позволяет получить доступ к члену базового класса, который скрыт "за" членом производного класса.
- •Многоуровневая иерархия
- •Переменные базового класса и производного класса
- •Виртуальные методы
- •Абстрактные методы и классы
- •Запрет наследования
Использование защищенного доступа
В нашем примере поля x и у базового класса были открыты для доступа (public). Если убрать public, то поля автоматически станут закрытыми для доступа (private), в том числе и для доступа из производного класса. Решить проблему доступа к закрытым полям базового класса из производного можно двумя способами: используя свойства класса или спецификатор protected. При объявлении какого-то члена класса с помощью спецификатора protected, он становится закрытым для всех классов, кроме производных.
class DemoPoint
{
protected int x;
protected int y;
public void Show()
{
Console.WriteLine("({0}, {1})",x, y);
}
}
class DemoLine : DemoPoint
{
public int xEnd;
public int yEnd;
publicnewvoidShow()
{
x=2;y=2; //доступ к закрытым полям базового класса
Console.WriteLine("({0}, {1})-({2}, {3})",x,y,xEnd,yEnd);
}
}
class Program
{
static void Main()
{
DemoPoint point = new DemoPoint();
point.Show();
DemoLine line = new DemoLine();
//line.x = 2; line.y = 2; //доступ к полям закрыт
line.xEnd = 10; line.yEnd = 10;
line.Show();
}
}
}
Обратите внимание на то, что доступ к полям х и yиз класса Program невозможен, а из производного класса DemoLine возможен.
Наследование конструкторов
В иерархии классов как базовые, так и производные классы могут иметь собственные конструкторы. При этом конструктор базового класса создает часть объекта, соответствующую базовому классу, а конструктор производного класса — часть объекта, соответствующую производному классу. Так как базовый класс не имеет доступа к элементам производного класса, то их конструкторы должны быть раздельными.
В предыдущем примере классы создавались за счет автоматического вызова средствами С# конструктора по умолчанию. Добавим конструктор только в производный класс DemoLine:
class DemoPoint
{
protected int x;
protected int y;
public void Show()
{
Console.WriteLine("({0}, {1})",x, y);
}
}
class DemoLine : DemoPoint
{
public int xEnd;
public int yEnd;
new public void Show()
{
Console.WriteLine("({0}, {1})-({2}, {3})", x, y, xEnd, yEnd);
}
public DemoLine(int x1, int y1, int x2, int y2) //конструктор производного класса
{
x = x1; y = y1;
xEnd = x2; yEnd = y2;
}
}
class Program
{
static void Main()
{
DemoPoint point = new DemoPoint(); //вызывается конструктор по умолчанию
point.Show();
DemoLineline=newDemoLine(2, 2, 10, 10); //вызывается собственный конструктор
line.Show();
}
}
В данном случае конструктор определяется только в производном классе, поэтому часть объекта, соответствующая базовому классу, создается автоматически с помощью конструктора по умолчанию, а часть объекта, соответствующая производному классу, создается собственным конструктором.
Если же конструкторы определены и в базовом, и в производном классе, то процесс создания объектов несколько усложняется, т.к. должны выполниться конструкторы обоих классов. В этом случае используется ключевое слово base, которое имеет два назначения: