wiki:kuormittaminen
Last modified 14 months ago Last modified on 2016-01-20 19:36:01

Luentomonisteen täydennykset » Aliohjelmien kuormittaminen


* Tämä sivu on siirretty TIM-järjestelmään. *


C#:ssa aliohjelmia ja funktioita voidaan kuormittaa (eng. overload) parametrien suhteen. Tämä tarkoittaa, että ohjelmassa voi olla monta samannimistä aliohjelmaa, joilla on eri määrä (tai eri tyyppisiä) parametreja. Tätä voidaan hyödyntää siten, että se funktio joka ottaa enemmän parametreja, osaa tehdä enemmän (tai tarkemmin) asioita kuin vähemmän parametreja ottava funktio.

Yksinkertaisin esimerkki

Otetaan aluksi mahdollisimman yksinkertainen esimerkki kuormittamisesta. Käytetään tapauksena funktioita, jotka osaavat lisätä lukuja toisiinsa.

Tehdään aluksi funktio, joka palauttaa kahden luvun summan.

public static double Summa(double a, double b)
{
  return a + b;
}

Tätä voitaisiin kutsua esimerkiksi Main-pääohjelmasta kirjoittamalla

double summa = Summa(5, 10.5);

Sitten keksimme, että hei, tarvitsemme myös funktion, joka osaa summata kolme lukua, ja haluaisimme kutsua sitä kirjoittamalla

double summa = Summa(5, 10.5, 30.9);

Kirjoitetaan samanniminen funktio, mutta annetaan sille funktion määrittelyrivillä (eng. function signature) kolme parametria kahden sijaan. Toteutetaan funktio myös saman tien.

public static double Summa(double a, double b, double c)
{
  return a + b + c;
}

Mutta nyt huomaamme, että meillä on melkein sama koodi näissä kahdessa funktiossa. Muutetaan ensimmäistä funktiota siten, että kutsutaan ensimmäisestä funktiosta (joka osaa vähemmän) toista funktiota (joka osaa enemmän). Annetaan kolmanneksi summattavaksi luvuksi (siis kolmanneksi parametriksi) 0.

public static double Summa(double a, double b)
{
  return Summa(a, b, 0);
}

Tämän esimerkin avulla opimme, mitä kuormittaminen tarkoittaa. Seuraava esimerkki valottaa kuormittamisen hyötyjä paremmin.

Vakiokokoinen lumiukko vs ukon koko parametrina

Voimme luoda vakiokokoisen lumiukon seuraavalla aliohjelmalla.

/// <summary>
/// Aliohjelma piirtää vakiokokoisen lumiukon
/// annettuun paikkaan.
/// </summary>
/// <param name="peli">Peli, johon lumiukko tehdään.</param>
/// <param name="x">Lumiukon alimman pallon x-koordinaatti.</param>
/// <param name="y">Lumiukon alimman pallon y-koordinaatti.</param>
public static void PiirraLumiukko(Game peli, double x, double y)
{
  PhysicsObject alapallo, keskipallo, ylapallo;
  alapallo = new PhysicsObject(2 * 100.0, 2 * 100.0, Shape.Circle);
  alapallo.X = x;
  alapallo.Y = y;
  peli.Add(alapallo);
  
  keskipallo = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
  keskipallo.X = x;
  keskipallo.Y = alapallo.Y + 100 + 50;
  peli.Add(keskipallo);
  
  ylapallo = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
  ylapallo.X = x;
  ylapallo.Y = keskipallo.Y + 50 + 30;
  peli.Add(ylapallo);
}

Voimme kutsua tätä aliohjelmaa Begin:stä vaikkapa seuraavasti.

PiirraLumiukko(this, 0, Level.Bottom + 200.0);

Mutta entäs jos haluaisimmekin piirtää tämän lisäksi joskus eri kokoisiakin ukkoja? Toisin sanoen, joskus meille riittää, että PiirraLumiukko tekisi meille "vakiokokoisen" ukkojen lisäksi myös halutessamme jonkun muun kokoisen ukelin. Kutsut Begin:ssä voisivat näyttää tältä.

// Vakiokokoisen ukon kutsuminen (alapallon koko 2 * 100)
PiirraLumiukko(this, -200, Level.Bottom + 300.0);

// Samannimisen aliohjelman käyttäminen 
// pienemmän ukon tekemiseen (alapallon koko 2 * 50)
PiirraLumiukko(this, 0, Level.Bottom + 200.0, 50.0);

Mutta nyt visual studio antaa virheilmoituksen

No overload for method 'PiirraLumiukko' takes 4 arguments.

Jotenka kirjoitetaan uusi aliohjelma, jonka nimeksi tulee PiirraLumiukko (kyllä, samanniminen), mutta peli-parametrin ja paikan lisäksi parametrina annetaan myös alapallon säde.

public static void PiirraLumiukko(Game peli, double x, double y, double sade)
{
 // tähän kirjoitetaan kohta koodia...
}

Siirretään nyt koodi alkuperäisestä aliohjelmasta tähän uuteen, ja laitetaan pallojen säde riippumaan parametrina annetusta säteestä. Lisäksi laitetaan keski- ja yläpallon paikat riippumaan pallojen koosta! Uusi (neljäparametrinen) aliohjelma näyttäisi nyt seuraavalta.

public static void PiirraLumiukko(Game peli, double x, double y, double sade)
{
    PhysicsObject alapallo, keskipallo, ylapallo;
    alapallo = new PhysicsObject(2 * sade, 2 * sade, Shape.Circle);
    alapallo.X = x;
    alapallo.Y = y;
    peli.Add(alapallo);

    // keskipallon koko on 0.5 * sade
    keskipallo = new PhysicsObject(2 * 0.5 * sade, 2 * 0.5 * sade, Shape.Circle);
    keskipallo.X = x;
    keskipallo.Y = alapallo.Y + alapallo.Height / 2 + keskipallo.Height / 2;
    peli.Add(keskipallo);

    // ylapallon koko on 0.3 * sade
    ylapallo = new PhysicsObject(2 * 0.3 * sade, 2 * 0.3 * sade, Shape.Circle);
    ylapallo.X = x;
    ylapallo.Y = keskipallo.Y + keskipallo.Height / 2 + ylapallo.Height / 2;
    peli.Add(ylapallo);
}

Nyt voimme kutsua kolmeparametrisesta PiirraLumiukko-aliohjelmasta tuota "versiota", joka osaa tehdä asioita enemmän ilman, että copy-pastetamme koodia!

public static void PiirraLumiukko(Game peli, double x, double y)
{
    PiirraLumiukko(peli, x, y, 100);
}

Koko ohjelmamme näyttäisi nyt tältä.

Attachments