C# перегружаемые методы

Для начала следует определиться с тем, что такое перегружаемые методы и как с ними работать.

Перегружаемые методы идут по пути полиморфизма и также как и виртуальные методы, позволяют переопределять один и тот же метод, с одним и тем же именем.

Если быть точнее, то перегружаемые методы не переопределяют определенный метод, а лишь дополняют его очередной измененной копией.

Сразу приведем пример в коде, что бы Вам было понятнее.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{

//
some_func();
some_func( "Hello might" );

Console.ReadKey();

}

public static void some_func()
{

Console.WriteLine("Got no text");

}

 

public static void some_func(string some_text)
{

Console.WriteLine("Got text : " + some_text);

}
}
}

 

Приведенный выше пример выведет на экран следующие линии:

Got no text

Got text : Hello might

 

 

Т.е. мы создали два одинаковых по имени метода, но с разными входными параметрами.

Это и называется перегрузкой метода, когда у одного метода имеются разные представления.

 

Но, как же их следует различать?

Достаточно просто, они различаются по входным параметрам.

А если быть точнее, по типам входных параметров или их количеством.

То есть Вы можете объявить хоть 100500 одинаковых методов, но они должны различаться по количеству входных параметров, либо по их типу.

Следующий пример наглядно это демонстрирует.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{

//
some_func();
some_func( "Hello might" );
some_func( "Hello might", "How are you?" );
some_func( 100, 500 );

Console.ReadKey();

}

public static void some_func()
{

Console.WriteLine("Got no text");

}


public static void some_func(string some_text)
{

Console.WriteLine("Got text : " + some_text);

}


public static void some_func(string some_text, string some_text2)
{

Console.WriteLine("Got two lines : " + some_text + " -and- " + some_text2);

}


public static void some_func(int some_text, int some_text2)
{

Console.WriteLine("Got two numbers : " + some_text + " -and- " + some_text2);

}

}
}

 

После запуска приведенного кода на экране появятся следующие надписи:

Got no text

Got text : Hello might

Got two lines : Hello might -and- How are you?

Got two numbers : 100 -and- 500

 

Как видите, мы объявили 4 одинаковых метода, но с разными параметрами.

C# сам узнает, какие передаются параметры и в каком количестве, после чего вызывает тот, который подходит по типу указанных параметров и/или их количеству.

 

Зачем это нужно?

Во первых, это очень удобно.

Во вторых, улучшает код.

В третьих, перегружать можно не только простые методы, но и конструкторы классов, но об этом ниже в статье.

А для более наглядного примера, приведем язык C.

В C есть метод ABS(), который возвращает абсолютное значение целого числа.

Также, в C есть метод LABS(), который возвращает абсолютное значение длинного целого числа.

А еще в C есть метод FABS(), который возвращает абсолютное значение числа с плавающей точкой обычной(одинарной) точности.

Но, по сути, все эти 3 функции выполняют одну и ту же задачу, лишь различаясь по входным параметрам.

Это происходит потому, что C не поддерживает перегружаемые методы и приходится каждую функцию и/или ее копию называть уникальным именем.

А в C# есть всего одна функция ABS() в пространстве имен System, в классе Math, и эта одна функция выполняет функцию трех перечисленных в C, вот почему возможность перегружать методы настолько удобна.

 

Что скрывается под копотом?

C# умеет различать перегружаемые функции и вообще позволяет с ними работать благодаря сигнатурам.

Сигнатуры обозначают имя метода, а также его параметры, их количество и типы.

Таким образом, в C# один класс не может иметь один и тот же метод с одинаковым количество параметров и/или типами параметров.

Тип, возвращаемый методом не учитывается в сигнатурах, именно поэтому он никак не влияет на принятие решения языком C#.

Также, на решение C# не влияет модификатор params.

 

Перегрузка констуктора класса.

Конструктор того, или иного класса также можно перегружать.

С ходу пример:

 

class Animals
{

protected string animal_name;

public Animals()
{
animal_name = "undefined";
Console.WriteLine(" There is no name of animal ");
}

public Animals(string name)
{
animal_name = name;
Console.WriteLine(" Animal name is " + name);
}

public virtual void Print_Name()
{
//
Console.WriteLine("Animal name is : " + animal_name);
}
}

 

И создаем два экземпляра класса:

static void Main(string[] args)
{

//
Animals dog = new Animals();
Animals cat = new Animals("Jonny Catsvill");
Console.ReadKey();

}

В консоле появится следующий текст:

 There is no name of animal 

Animal name is : Jonny Catsvill

 

Но, это лишь простые примеры, в деле же перезагрузка конструкторов полезна, например, для задания стандартных значений полям и не дублирование одного и того же кода.

Например, один из перегружаемых констукторов может вызвать другую свою перегружаемую копию.

Пример:

 

class Animals
{

protected string animal_name;

public Animals() : this("Kvon Cho Wong")
{
}

public Animals(string name)
{
animal_name = name;
Console.WriteLine(" Animal name is " + name);
}

public virtual void Print_Name()
{
//
Console.WriteLine("Animal name is : " + animal_name);
}
}

 

При таком вызове:

 

static void Main(string[] args)
{

//
Animals dog = new Animals();
Animals cat = new Animals("Jonny Catsvill");
Console.ReadKey();

}

 

Выведет на экран следующий текст:

Animal name is : Kvon Cho Wong

Animal name is : Jonny Catsvill

 

Если Вы задаетесь вопросом того, будет ли выполняться тело "пустого" конструктора, то ответ на этот вопрос - да, будет, поскольку работает эта конструкция по принципу наследования.

То есть, когда Вы создате экземпляр класса Animals и не передаете ничего в его параметрах, этот экземпляр конструкцией this обращается сам к себе и вызывает свой же метод, но передает стандартное значение, то есть он вызывает свою перегруженную копию.

А после того, как перегруженная копия закончит свою работу, управление опять вернется к "пустому" конструктору, и его тело исполнится.

 

Подводим итоги статьи.

Вот такой вот интересный пример.

Еще существуют такие понятия, как перегрузка индексатора и перегрузка операторов, но об этом уже в следующих статьях.

С Вам был Прайлер, всего наилучшего и приятного кодинга 

 C# кодинг   9050     0  7  17.05.2014
 Нравится?
 Расскажи друзьям
 Комментарии