Наследование и полиморфизм
Наследование является одним из принципов ООП.
Основы классификации и реализация механизмов повторного использования и модификации кода. Базовый класс задает общие признаки и общее поведение для классов-наследников.
Общие (наиболее общие) свойства и методы наследуются от базового класса, в дополнение к которым добавляются и определяются НОВЫЕ свойства и методы.
Таким образом, прежде всего наследование реализует механизмы расширения базового класса.
Реализация принципов наследования на примере:
using System;
namespace Inheritance_1
{
public class A
{
public int val1_A;
public void fun1_A (String str)
{
Console.WriteLine("A's fun1_A:" + str);
}
}
public class B:A
{
public int val1_B;
public void fun1_B (String str)
{
Console.WriteLine("B's fun1_B:" + str);
}
}
class Class1
{
static void Main(string[] args)
{
B b0 = new B();
// От имени объекта b0 вызвана собственная функция fun1_B.
b0.fun1_B("from B");
// От имени объекта b0 вызвана унаследованная от класса A функция fun1_A.
b0.fun1_A("from B");
}
}
}Наследование и проблемы доступа
Производный класс наследует от базового класса ВСЕ, что он имеет. Другое дело, что воспользоваться в производном классе можно не всем наследством.
Добавляем в базовый класс private -члены:
public class A
{
public int val1_A = 0;
public void fun1_A (String str)
{
Console.WriteLine("A's fun1_A:" + str);
this.fun2_A("private function from A:");
}
// При определении переменных
// в C# ничего не происходит без конструктора и оператора new.
// Даже если они и не присутствуют явным образом в коде.
private int val2_A = 0;
private void fun2_A (String str)
{
Console.WriteLine(str + "A's fun2_A:" + val2_A.ToString());
}
}И объект-представитель класса B в принципе НЕ может получить доступ к private данным — членам и функциям — членам класса A. Косвенное влияние на такие данные-члены и функции — члены – лишь через public -функции класса A.
Следует иметь в виду еще одно важное обстоятельство.
Если упорядочить все (известные) спецификаторы доступа C# по степени их открытости
то наследуемый класс не может иметь более открытый спецификатор доступа, чем его предок.
Используем еще один спецификатор доступа – protected. Этот спецификатор обеспечивает открытый доступ к членам базового класса, но только для производного класса!
public class A
{
:::::::::
protected int val3_A = 0;
}
public class B:A
{
:::::::::
public void fun1_B (String str)
{
:::::::::
this.val3_A = 125;
}
}
static void Main(string[] args)
{
:::::::::
//b0.val3_A = 125; // Это член класса закрыт для внешнего использования!
}Защищенные члены базового класса доступны для ВСЕХ прямых и косвенных наследников данного класса.
И еще несколько важных замечаний относительно использования спецификаторов доступа:
- в C# структуры НЕ поддерживают наследования. Поэтому спецификатор доступа protected в объявлении данных — членов и функций — членов структур НЕ ПРИМЕНЯЕТСЯ;
- спецификаторы доступа действуют и в рамках пространства имен (поэтому и классы в нашем пространстве имен были объявлены со спецификаторами доступа public ). Но в пространстве имен явным образом можно использовать лишь один спецификатор – спецификатор public, либо не использовать никаких спецификаторов.