Слайд 1Перегрузка и переопределение методов
Полиморфизм
Слайд 2Перегрузка методов
Полиморфизм
Слайд 3Пример 1
public class Overload
{
public void DisplayOverload(int
a){
Console.WriteLine("DisplayOverload " + a);
}
public void DisplayOverload(string a){
Console.WriteLine("DisplayOverload " + a);
}
public void DisplayOverload(string a, int b){
Console.WriteLine("DisplayOverload " + a + b);
}
}
Слайд 4Покажем вызов методов:
class Program
{
static void Main(string[] args)
{
Overload overload = new Overload();
overload.DisplayOverload(100);
overload.DisplayOverload("method overloading");
overload.DisplayOverload("method overloading", 100);
Console.ReadKey();
}
}
Слайд 5Перегрузка методов
Класс Overload содержит три метода, и все они называются
DisplayOverload, они различаются только типами параметров.
В C# (как и
в большистве других языков) мы можем создавать методы с одинаковыми именами, но разными параметрами, это и называется «перегрузка методов». Это значит, что нам нет нужды запоминать кучу имён методов, которые совершают одинаковые действия с разными типами данных.
Что нужно запомнить: метод идентифицируется не только по имени, но и по его параметрам.
Слайд 6Пример 2
public void DisplayOverload() { }
public int DisplayOverload(){ }
Слайд 7Тип возвращаемого значения метода
Здесь вы можете видеть две функции, которые
различаются только по возвращаемому типу, и скомпилировать это нельзя.
Что нужно
запомнить: метод не идентифицируется по возвращаемому типу, это не полиморфизм.
Слайд 8Пример 3
static void DisplayOverload(int a) { }
public void DisplayOverload(int
a) { }
public void DisplayOverload(string a){ }
Слайд 9Статические методы
Здесь присутствуют два метода, принимающих целое число в качестве
аргумента, с той лишь разницей, что один из них помечен
как статический.
Что нужно запомнить: модификаторы вроде static также не являются свойствами, идентифицирующими метод.
Слайд 10Пример 4
private void DisplayOverload(int a) { }
private void DisplayOverload(out
int a) {
a =
100;
}
private void DisplayOverload(ref int a) { }
Слайд 11Модификаторы доступа
Что нужно запомнить: на идентификатор метода оказывают влияние только
его имя и параметры (их тип, количество). Модификаторы доступа не
влияют. Двух методов с одинаковыми типами и количеством параметров существовать не может.
Слайд 12Пример 5
public void DisplayOverload(int a, string a) { }
public
void Display(int a)
{
string a;
}
Слайд 13Имена параметров
Что нужно запомнить: имена параметров должны быть уникальны. Также
не могут быть одинаковыми имя параметра метода и имя локальной
переменной, созданной в этом же методе.
Слайд 14Переопределение методов
Полиморфизм
Слайд 15Переопределение методов
Наследование — одна из основных концепций объектно-ориентированного программирования. Она
говорит о том, что поведение класса-предка может быть переопределено в
классе-потомке.
В наследуемых классах могут быть созданы методы с такими же именами, что и в родительском классе. Это называется переопределение методов.
Слайд 16Пример 1
public class A
{
public virtual void DoWork()
{
Console.WriteLine("class A");
}
}
public class
B : A
{
public override void DoWork()
{
Console.WriteLine("class B");
}
}
Слайд 17ключевое слово virtual как раз и говорит о том, что этот метод
может быть переопределен в потомке.
В классе B этот метод переопределен с помощью
ключевого слова override.
Слайд 18Вызов методов:
var a = new A();
var b = new B();
a.DoWork();
// class A
b.DoWork(); // class B
(b as A).DoWork(); // class
B
т.е. не зависимо от того, какого типа переменная, метод будет браться из реального класса.
Слайд 19Пример 2
public class A
{
public virtual void DoWork()
{
Console.WriteLine("class A");
}
}
public class
B : A
{
public void DoWork()
{
Console.WriteLine("class B");
}
}
Слайд 20Перекрытие методов
Отличие в том, что отсутствует ключевое слово override. В этом
случае метод предка не переопределен, а перекрыт. В этой ситуации
наличие или отсутствие ключевого слова virtual в классе A не имеет значения.
Слайд 21Поведение такого класса будет отличаться:
var a = new A();
var b
= new B();
a.DoWork(); // class A
b.DoWork(); // class B
(b as
A).DoWork(); // class A
Слайд 22Выводы:
как мы видим, метод берется не из реального класса переменной,
а от типа, к которому переменная переопределена. Это неочевидное поведение
может быть причиной трудно находимых багов и делать так крайне не рекомендуется. Среда разработки подсветит перекрывающий метод как warning.
Если вам нужно именно такое поведение, нужно помечать перекрывающий метод ключевым словом new
Слайд 23Перекрытие метода:
public class B : A
{
public new void DoWork()
{
Console.WriteLine("class
B");
}
}