Метод (програмиране): Разлика между версии

от Уикипедия, свободната енциклопедия
Изтрито е съдържание Добавено е съдържание
Редакция без резюме
Редакция без резюме
Ред 103: Ред 103:
Динамичните методи за разлика от статичните са "вързани" към точно определен обект на дадения клас, и извършват манипулации въз основа на данните на дадения обект, а не на класа като цяло.
Динамичните методи за разлика от статичните са "вързани" към точно определен обект на дадения клас, и извършват манипулации въз основа на данните на дадения обект, а не на класа като цяло.
Ако имаме два обекта - примерно carA и carB - от клас Automobiles, и всеки от обектите пази в себе си данни за последното показание на километража и заредените литри гориво, тогава извикването на carA.GetAverageMPG() и съответно на carB.GetAverageMPG() ще връща разхода на гориво за конкретния обект, ползвайки данните от обекта. Динамичните методи се извикват чрез добавяне на името на обекта преди името на метода.
Ако имаме два обекта - примерно carA и carB - от клас Automobiles, и всеки от обектите пази в себе си данни за последното показание на километража и заредените литри гориво, тогава извикването на carA.GetAverageMPG() и съответно на carB.GetAverageMPG() ще връща разхода на гориво за конкретния обект, ползвайки данните от обекта. Динамичните методи се извикват чрез добавяне на името на обекта преди името на метода.

==Предефиниране на методи==
Предефинирането (Overloading) на метод е възможността да имаме методи с едно и също име, но с различен брой параметри, които да имат различен код в себе си. Това е възможно, тъй като компилатора различава един метод от друг не само по името, но и по броя (и типа) на параметрите предавани към него. Това ни позволява например да имаме процедура CalculateArea(), която да може да изчислява площта както на правоъгълник, така и на кръг (а по желание и на още геометрични фигури), стига броя и/или типа на подаваните параметри да е уникален. Метод с име CalculateArea(int height, int width) може да се ползва за изчисляване на площта на правоъгълник, а метод със същото име, но само с един параметър: CalculateArea(doube radius) да изчислява площта на кръг. Дори и ако решим да ползваме същото име за процедура за изчисляване площта на квадрат по този начин: CalculateArea(int side) то това ще е правилно от гледна точка на компилатора, макар че има 2 метода с по 1 параметър. Разликата е че единия път параметъра е double, а другия int. В последния случай трябва да се подхожда с повишено внимание, тъй като ако имаме окръжност с радиус примерно 2, запомнен в int променливата radius извикването на метода ще изчисли площта за квадрат, а не за кръг. Но е достатъчно да се извика с area = CalculateArea((double) radius) за да се извика коректния метод за кръг.
==Overriding на методи==

Версия от 15:16, 8 август 2013

Метод (Шаблон:Lang-en) в програмирането е съставна част от една програма, която решава конкретен проблем. Може както да приема параметри така и да връща стойност. Целта на писането на дадена програма е решаването на дадена задача. За да бъде ефективно решена дадена задача в програмирането, тя се разделя на подзадачи, разработват се алгоритми за решение на тези подзадачи и накрая тези подзадачи се сглобяват в цялостна програма. Обособените парчета код, решаващи дадената подзадача се наричат подпрограми (subroutines). В различните езици подпрограмите се срещат под други имена като функции (functions) или процедури (procedures). В C#, те се наричат методи (methods).

Най-простият пример за метод е "Main(…)", който винаги го декларираме между отварящата и затварящата скоба на нашия клас:

class HelloCSharp
{ // Отваряща скоба на класа
// Декларираме нашият метод между скобите на класа
    static void Main(string[] args)
    {
        Console.WriteLine("Hello C#!");
    }
} // Затваряща скоба на класа

Къде е позволено да декларираме метод

Всеки клас (class) има отваряща и затваряща фигурни скоби – "{" и "}", между който се пише програмният код. Даден метод може да съществува само ако е деклариран между отварящата "{" и затварящата "}" скоба на даден клас. Също така допълнително изискване, е методът да бъде деклариран извън имплементацията на друг метод. Ето и още един но по-сложен пример как се ползват методите и къде се декларират. Тази програма при въвеждане на две числа изкарва по-голямото, а кода за намиране на по-голямото число е изкаран в отделен метод (GetMaxCalculation):

using System;

internal class GetMax
{ // Отваряща скоба на класа

// Декларираме метода GetMaxCalculation и поставяме в него кода за намиране на по-голямото от две числа

    internal static double GetMaxCalculation(double firstNumber, double secondNumber)
    {
        double theMaxNumber = firstNumber;
        if (firstNumber < secondNumber)
        {
            theMaxNumber = secondNumber;
        }
        return theMaxNumber;
    }
// Декларираме метода Main()

    static void Main()
    {
        Console.Write("Enter number One: ");
        double numberOne = double.Parse(Console.ReadLine());
        Console.Write("Enter number Two: ");
        double numberTwo = double.Parse(Console.ReadLine());

        Console.WriteLine();

// Извикваме метода GetMaxCalculation и принтираме

        Console.WriteLine("The Biggest Number is: {0}", GetMaxCalculation(numberOne, numberTwo));
        Console.WriteLine();
    }
} // Затваряща скоба на класа

Методите могат да бъдат декларирани с и без параметър. Горният пример е на метод деклариран с два параметъра, т.е. internal static double GetMaxCalculation(double firstNumber, double secondNumber). Пример на метод без параметри е:

static int countNumber = 10;
internal static void PrintFirstOddNumbers()
{
    for (int number = 0; number < countNumber; number++)
    {
        if (number / 2 == 0)
        {
            Console.WriteLine(number);
        }
    }
}

Извикване на метод от друг клас

За да извикаме метод дефиниран в един клас от друг, то тогава той трябва да е или internal (достъпван само в съответното assembly) или public. Достъпът до метода става чрез името на класа. Private методи са видими само в съответният клас и не могат да бъдат достъпвани от друг.

using System;

class SimpleCalculations
{
    double maxValue = GetMax.GetMaxCalculation(1.02, 3);
}

Ако искаме да разберем кой метод извиква нашият код може да използваме StackTrace(using System.Diagnostics;).

StackTrace stackTrace = new StackTrace();
var traceMethod = stackTrace.GetFrame(1).GetMethod().Name;

По този начин получаваме името на метода който извиква.

Основни правила за създаване и работа на един метод

1. Всеки един метод трябва да решава само една точно определена задача. Обособяването като метод на парче код което решава няколко задачи (дори и свързани помежду си) води до затруднена четимост на програмата като цяло и до затруднено редактиране на кода.
2. Името на метода трябва да е описателно и да отговаря на това, което изпълнява дадения метод. Ако името на метода се получи прекалено дълго това означава че този метод не решава само една задача. Например метод с име GetUserName() е пример за име което описва съвсем ясно какво прави той. Ако при писане на метода стигнете до име от типа на GetUserNameAndPasswordAndCheckInDataBaseForUserDetails() това трябва да ви покаже, че "натоварвате" един метод с повече от една функция.
3. Един метод трябва да "знае" за "околната среда" точно толкова колкото е необходимо за да може да си свърши работата, и трябва да бъде видим само от методи, които биха могли да имат работа с него. Предаването на масив от данни или структура към метод, който има нужда само от един елемент от тези данни е грешен подход и трябва да се избягва.
4. Винаги когато в програмата нещо трябва да се извърши на повече от едно място то този код трябва да се обособи в отделен метод. По този начин евентуални бъдещи корекции ще трябва да се направят само в тялото на метода, а не на няколко места в основната програма, или в други методи.

Статични и динамични методи

В езика C# методите могат да бъдат "привързани" както към даден клас като цяло, така и към дадена инстанция (елемент) на дадения клас.Когато метода бъде дефиниран с ключовата дума static пред дефиницията си, то той е статичен. Този метод работи не върху конкретен обект от класа, а върху данни от целия клас. Ако например имаме клас "автомобил" и направим статичен метод за изчисляване на разхода на гориво, то този метод няма да се интересува за кой точно автомобил става въпрос. Той ще очаква да му се подадат като параметри пробега и изразходените литри гориво, и ще връща резултата в литри на 100 км. Така всички обекти, наследници на клас "автомобил" ще могат да изчисляват разхода си, ползвайки този метод. Особеност на статичните методи е това, че те могат да се извикват дори и да няма нито един обект от дадения клас, тъй както както казахме те са "вързани" към самия клас, а не към определен обект от него. Можем да извикаме Automobile.GetAverageMPG(miles, gallons) без да се интересуваме дали има вече създаден обект от клас Automobiles. Както се забелязва от примера статичния метод се извиква като се укаже името на клас преди името на метода.
Динамичните методи за разлика от статичните са "вързани" към точно определен обект на дадения клас, и извършват манипулации въз основа на данните на дадения обект, а не на класа като цяло. Ако имаме два обекта - примерно carA и carB - от клас Automobiles, и всеки от обектите пази в себе си данни за последното показание на километража и заредените литри гориво, тогава извикването на carA.GetAverageMPG() и съответно на carB.GetAverageMPG() ще връща разхода на гориво за конкретния обект, ползвайки данните от обекта. Динамичните методи се извикват чрез добавяне на името на обекта преди името на метода.

Предефиниране на методи

Предефинирането (Overloading) на метод е възможността да имаме методи с едно и също име, но с различен брой параметри, които да имат различен код в себе си. Това е възможно, тъй като компилатора различава един метод от друг не само по името, но и по броя (и типа) на параметрите предавани към него. Това ни позволява например да имаме процедура CalculateArea(), която да може да изчислява площта както на правоъгълник, така и на кръг (а по желание и на още геометрични фигури), стига броя и/или типа на подаваните параметри да е уникален. Метод с име CalculateArea(int height, int width) може да се ползва за изчисляване на площта на правоъгълник, а метод със същото име, но само с един параметър: CalculateArea(doube radius) да изчислява площта на кръг. Дори и ако решим да ползваме същото име за процедура за изчисляване площта на квадрат по този начин: CalculateArea(int side) то това ще е правилно от гледна точка на компилатора, макар че има 2 метода с по 1 параметър. Разликата е че единия път параметъра е double, а другия int. В последния случай трябва да се подхожда с повишено внимание, тъй като ако имаме окръжност с радиус примерно 2, запомнен в int променливата radius извикването на метода ще изчисли площта за квадрат, а не за кръг. Но е достатъчно да се извика с area = CalculateArea((double) radius) за да се извика коректния метод за кръг.

Overriding на методи