CS-opas:Ensimmäinen ohjelma C
Mureakuha
- Teknisistä rajoituksista johtuen artikkelin yllä näkyvä otsikko on virheellinen. Oikea otsikko on C#-opas: Ensimmäinen ohjelma C#:lla.
Sisällysluettelo |
Tervehtijäohjelma
// Tervehtija.cs
using System;
namespace Harjoitus
{
public class Tervehtija {
public static void Main() {
Console.Write("Hei mitäpä kuuluu? ");
String vastaus = Console.ReadLine();
Console.WriteLine("Vai, että {0}",vastaus);
}
}
}
using System; rivillä kerrotaan kääntäjälle, että ohjelmassa on käytössä luokkia tai alinimiavaruuksia System nimiavaruudessa. Rivi ei ole pakollinen, mutta tällöin jouduttaisiin kirjoittamaan luokkien alkuun myös System., jotta kääntäjä tietää missä luokka on. Nyt kääntäjä etsii ensin juuresta luokkaa Console, kun se ei löydy sieltä se etsii System nimiavaruudesta, jossa Console luokka sijaitsee muiden .NET Framework luokkien kanssa. Ilman using määrittelyä Console luokkaa tulisi kutsua tähänä tapaan System.Console.Write("Hei mitäpä kuuluu? "); nimiavaruudet erotellaan toisistaan ja luokista piste operaattorilla. kuten esimerkissä huomasit.
namespace Harjoitus Seuraavaksi määritellään omalle luokalle nimiavaruus jonne luokka kuuluu. dotNET Frameworkin luokat on System nimiavaruudessa, mutta omille luokille voidaan tehdä oma nimiavaruus kuten tässä tapauksessa Harjoitus. Yleensä suositus olisi nimiavaruudelle Yritys.Projekti muotoa. Eli nimiavaruuksilla voi olla alinimiavaruuksia ja myös namespaceja voi olla sisäkkäin, mutta myös pisteellä erottaminen kerralla onnistuu. Nimiavaruuden sisältö kirjoitetaan namespace:n jälkeiseen aaltosulkeiden sisään.
public static void Main() { Tämä on Main metodi, josta ohjelman suoritus alkaa. Main metodi voisi ottaa myös parametreja, mutta ei ole pakko. Tästä myöhemmissä luvuissa lisää param avainsanan yhteydessä. Main metodi on staattinen, koska luokasta ei ole olemassa ilmentymää, kun ohjelma käynnistyy. Näin on mahdollistettu Main metodin kutsuminen ohjelman alussa.
Console.Write("Hei mitäpä kuuluu? "); Nyt kutsutaan Console luokan staattista metodia Write, jolle annetaan parametrinä teksti, jonka se tulostaa näytölle ilman rivin vaihtoa. Write metodille voidaan antaa useampi parametri, jotka mahdollistavat helposti muuttujien sisällön tulostamisen näytölle. kts WriteLine rivi, jossa on annetta vastaus muuttuja toiseksi parametriksi.
String vastaus = Console.ReadLine(); Tällä rivillä esitelty vastaus muuttuja, joka sisältää String tyyppistä tietoa. Tieto vastaus muutujaan tulee ReadLine metodilta, joka lukee käyttäjän kirjoittaman rivin ja palauttaa sen. '='-operattorilla sijoitetaan ReadLine metodin palauttama tieto vastaus muuttujaan.
Console.WriteLine("Vai, että {0}",vastaus); WriteLine metodi kirjoittaa kokonaan uuden rivin. Nyt riville on käsketty kirjoittaa "Vai, että {0}", mutta sitten vastaus muuttuja, johon käyttäjän syöte on tallennettu tuleekin toiseksi parametriksi. Eli toinen parametri tiedon tieto kirjoitetaan {0} merkinnän päälle, jos parametreja olisi useampi, niin esim neljännen parametrin tieto kirjoitettaisiin merkinnän {2} päälle jne.
Lopussa sitten suljetaan avatut aaltosulkeet Main metodille, Luokalle Tervehtijä ja nimiavaruudelle Harjoitus.
Ensimmäinen olio
using System;
namespace Harjoitus
{
public class Henkilo {
public String nimi;
private int ika;
public static void Main() {
Henkilo henkilo = new Henkilo("Jaska",14);
Console.WriteLine(henkilo.nimi);
henkilo.nimi = "Timppa";
Console.WriteLine(henkilo.nimi);
Console.WriteLine("{0}", henkilo.GetIka());
henkilo.SetIka(16);
Console.WriteLine("{0}", henkilo.GetIka());
}
public Henkilo(String nimi, int ika) {
this.nimi = nimi;
this.ika = ika;
}
/*
Voitaisiin myös käyttää Propertyjä esim:
public string Ika{
get{ return this.ika; }
set{ if(!this.ika.Equals(value)) this.ika = value; }
}
*/
public void SetIka(int ika) {
this.ika = ika;
}
public int GetIka() {
return this.ika;
}
}
}
- public String nimi;
nimi muuttuja on julkinen. Tälläistä muuttujaa voidaan muuttaa esimerkin mukaisesti henkilo.nimi = "Timppa"; Tämä on tehokas, mutta ei erityisen turvallinen.
- private int ika;
ika muuttuja on muutettu yksityiseksi, joten se on nyt turvallisempi, koska sitä voidaan ainoastaan, metodien kautta käyttää, mutta vain tässä luokassa ei jälkeläisissä. katso seuraava esimerkki. Mikäli kokeilet muuttaa Main metodissa ikää samalla tavalla kun nimeä, tapahtuu virhe. Tämän takia koodissa on kaksi metodia Set ja Get kirjoitettuna iän muuttamista varten. Mikäli tämä tuntuu vaikealta, paljastetaan että C#:ssa on tähän pelastus kts. property myöhemmistä luvuista.
public Henkilo(String nimi, int ika) {
this.nimi = nimi;
this.ika = ika;
}
Tämä on Henkilo luokan rakentaja, joka ottaa vastaan kaksi parametria ja asettaa ne olion muistiin, jotka luokan alussa on määritetty.
public void SetIka(int ika) {
this.ika = ika;
}
public int GetIka() {
return this.ika;
}
}
Koska olion ika-muuttuja on yksityinen, niin sen arvoa pitää muutaa metodien avulla. return this.ika; return käskyllä metodi palauttaa nyt olion ika-muuttujan, joka koodissa kutsuttiin näin
henkilo.SetIka(16); //Asetti iän
Console.WriteLine("{0}", henkilo.GetIka()); //Palauttaa iän
Periytyminen
Kantaluokka
Kantaluokkana on henkilö luokka, jota on jonkun verran muutettu
using System;
namespace Harjoitus
{
public class Henkilo {
public String nimi;
protected int ika;
//tehdään ika muuttujasta suojattu, jolloin perivä
//luokka voi muuttaa sitä.
private int id;
//suojataan id, että sitä ei voi myöhemmin enää muuttaa
public Henkilo(String nimi, int ika) {
this.nimi = nimi;
this.ika = ika;
//Random oliolla voidaan luoda satunnaisluku
Random random = new Random();
//Random next arpoo uuden luvun, joka on
//0:sta annettuun arvoon eli nyt
//suurin int tyypin arvo
this.id = random.Next(int.MaxValue);
//Kirjoitetaan kommentti, kun olio on luoto
Console.WriteLine("Henkilö luotu");
}
public void KayntiKortti() {
//Perus kamaa
Console.WriteLine("Nimi: {0}",this.nimi);
Console.WriteLine("Ikä: {0}",this.ika);
Console.WriteLine("ID: {0}",this.id);
}
public int ID() {
//tämä on ainut tapa selvittää id
//huomaathan, että id asetetaan kerran
//rakentajassa ja sen jälkeen muuttaminen
//on mahdotonta
return this.id;
}
}
}
Lapsiluokka ja Main
using System;
namespace Harjoitus
{
public class Tyontekija : Henkilo {
//esitellään uusi muuttuja
protected String ammatti;
public void KayntiKortti()
{
base.KayntiKortti(); //Kutsutaan kantaluokan metodia
Console.WriteLine("Ammatti:{0}",this.ammatti);
}
public void KasvataIkaa() {
this.ika++; //ika on protected, joten sitä
//voidaan muuttaa lapsi luokassa
//privatena tämä ei toimisi
Console.WriteLine("Uusi ikä on {0}",this.ika);
}
public Tyontekija(String nimi, int ika, String ammatti)
:base(nimi, ika) { //base kutsuu kantaluokan rakentajaa
this.ammatti = ammatti;
Console.WriteLine("Työntekijä luotu");
}
public static void Main() {
Tyontekija t1 = new Tyontekija("Pekka",45,"koodaaja");
Console.WriteLine();
t1.KayntiKortti();
Console.WriteLine();
t1.KasvataIkaa();
Console.WriteLine();
//Olion voi tallentaa kantaluokaksi esiteltyy
//muuttujaan, myutta tällöin voidaan vain
//käsitellä kantaluokan metodeja ja muuttujia.
//Poikkeus on virtuaaline metodi, josta myöhemmin lisää
Henkilo t2 = new Tyontekija("Jussi",18,"kalastaja");
Console.WriteLine();
t2.KayntiKortti(); //huomaa tämä on kutsuu kantaluokaa
//t2.KasvataIkaa(); //Tätä ei ole kantaluokassa, ei toimi
Console.WriteLine(); //Tyhjä rivi
//Tarkistetaan onko t2:n Työntekija
if(t2 is Tyontekija) {
Tyontekija tmp = (Tyontekija)t2; //Tyyppi muunnos
tmp.KayntiKortti(); //Työntekijän käyntikortti
}
Console.WriteLine();
//Kyseisen tarkistuksen voi tehdä nopeammin as käskyllä
Tyontekija t3;
t3 = t2 as Tyontekija;
//as operaattori palauttaa null,
//jos muunnos ei ole mahdollinen
if(t3 != null) {
t3.KayntiKortti();
}
}
}
}
Loppukaneetti tälle luvulle
Nyt on kerrottu mistä ohjelma alkaa ja mitä olio-ohjelmointi on. Tosin vielä puuttuu paljon, jotta olio-ohjelmoinnista saataisiin kaikki tarpeellinen irti. Samoin metodien hienouksia käsitellään tulevissa luvuissa enemmän.
