Grundkurs i C-Sharp - Statiska medlemmar
Förord
Ibland vill man att den information som man lagrar i en klass skall vara delad av alla objekt av den typen av en klass. Något som är statiskt tillhör inte ett unikt objekt utan tillhör alla objekt som består av samma typ av klass som den med det statiska innehållet.Innehåll
»»
»
»
»
»
Relaterade artiklar
» Grundkurs i C-Sharp - Arv» Grundkurs i C-Sharp - Gränssnitt
» Grundkurs i C-Sharp - Introduktion
» Grundkurs i C-Sharp - Namnrymder
» Grundkurs i C-Sharp - Polymorphism
» Grundkurs i C-Sharp - Strukturer
» Grundkurs i C-Sharp - Undantagshantering
» Grundkurs i C-Sharp - Åtkomstmodifiering
» Grundkurs i C-Sharp - Överlastning
När man vill deklarera något som statiskt markerar man det med nyckelordet static. I C-Sharp kan följande deklareras som statiska.
I denna artikel kommer jag att diskutera punkt ett till fyra, då punkt fem är en artikel för sig. Låt oss ta en titt på vad statiska medlemmar i en klass deklareras, används och fungerar.
Ett statiskt fält är det samma som ett fält som delas mellan alla object av den klassen där det är placerat. Detta betyder att fältet i samliga objekt pekar till samma minnesadress och om en av klasserna ändrar värdet på fältet så kommer det automatiskt att ändras hos samtliga objekt. Låt oss skapa ett enkelt exempel som visar hur det fungerar. Vi kommer att lägga till en räknare i vår klass, som ökas varje gång ett nytt objekt av samma klass skapas. I samma klass lägger vi in en metod som returnerar hur många objekt det finns.
Vi kommer nu att skapa två olika objekt av klassen Order och skriva ut värdet på fältet vid en rad olika tillfällen för att visa att räknaren ökar automatiskt i båda objekten.
Som ni kan se ökas värdet på Count fältet i objektet a när man skapar objektet b. Detta är pga. som jag sa tidigare, att fältet delar på samma minnesadress.
Statiska metoder har en lite annan innebörd än ett statiskt fält. En statisk metod kan man anropa utan att man har tillgång till ett objekt av den klass där metoden befinner sig. Ni behöver inte titta längre än till det förra exemplet där ni ser att jag anropade WriteLine() metoden i klassen Console, vilket inte är ett namn på ett objekt av en klass utan namnet på klassen där WriteLine() metoden finns.
Detta är speciellt användbart om man har vissa metoder som man använder väldigt ofta och inte vill behöva ha ett objekt tillgängligt varje gång. Låt oss skapa en enkel matte-klass för att visa hur det skulle gå till att skapa en klass med statiska metoder.
Som ni ser har jag valt att inte ha med en metod för att dividera två heltal med varandra. Detta är pga. av att resultatet med största sannolikhet skulle kunna bli ett decimaltal och då skulle jag behöva blanda in kod för att konvertera (type casting) och eftersom jag vill att fokus skall placeras på det faktum att metoderna är statiska så valde jag bort det.
Hur använder vi då våra statiska metoder? Det är enkelt, ta en titt på följande exampel som visar hur man använder samtliga tre metoder i klassen Math utan att ha tillgång till ett objekt av typen Math.
Även om det inte är helt relaterat till statiska metoder så kan jag nämna att om man har en klass som Math, där man bara har statiska metoder så kan det vara lämpligt att hindra folk från att skapa objekt av denna klass då det inte finns någon vits med det. För att hindra detta behöver vi bara göra en liten modifiering, nämligen att lägga till en privat konstruktor.
Eftersom klassen inte innehåller någon publik konstruktor, utan endast en privat så är det omöjligt att skapa ett object av klassen på följande sätt.
En sista kommentar om statiska metoder är att de inte kan deklareras som abstract, virtual eller override för då kommer man att få ett fel när man prövar att kompilerar.
Precis som med statiska metoder, så kan man skapa statiska attribut som man anropar utan att ha tillgång till ett objekt av klassen där attributet befinner sig. Man deklarerar sitt attribut på exakt samma sätt, bara det att man lägger till nyckelordet static i deklarationen.
Låt oss bygga ut vår Math klass så att den kan returnera ett versions nummer. Detta nummer kan vara lämpligt att komma åt utan att ha till gång till ett Math objekt så vi deklarerar attributet som statiskt.
För att nu ta reda på vilken version som den befintliga Math versionen är, så kan man helt enkelt göra på följande sätt.
Ibland kan det finnas situationer när man vill att en konstruktor skall anropas innan man anropar någon av de statiska metoderna i en klass. Detta kan t.ex. vara för att sätta vissa startvärde eller liknande saker, innan det att metoden exekveras.
För detta finns det statiska konstruktorer. Det är helt enkelt en konstruktor som deklarerats med nyckelordet static. Denna konstruktor anropas när första objektet av klassen skapas eller innan den första statiska metoden exekveras.
Det finns en del begränsningar med statiska konstruktorer som man måste ha i åtanke när man kan deklarerar dem. En statisk konstruktor kan inte:
Tyvärr sviktar min fantasi lite här, för att kunna hitta på någon som skulle kunna vara i närheten till ett praktiskt exampel på vad man skulle kunna använda en statisk konstruktor till, så ni får hålla till godo med hur det skulle se ut att lägga till en statisk konstruktor i vår Math klass, som inte gör något. Självklart är tanken med en statisk konstruktor att man skall initiera klassen när en referens till den görs första gången, men med Math klassen finns det inga data att initiera.
Som med allt annat så har statiska fält, metoder, attribut och konstruktorer stor användning i objektorienterad programmering, men med en liten varning. Planera din design noga och använd inte statiska klass-medlemmar om du verkligen inte behöver.
Andreas bor i Helsingborg där han studerar Software Engineering vid Lunds Tekniska Högskola. Han har många års erfarenhet inom både Windows samt internet baserad programmering inom en rad olika programmeringsspråk. Ni kan komma i kontakt med Andreas på andreas@selfinflicted.org.
- Fält
- Metoder
- Attribut
- Konstruktorer
- Operander
I denna artikel kommer jag att diskutera punkt ett till fyra, då punkt fem är en artikel för sig. Låt oss ta en titt på vad statiska medlemmar i en klass deklareras, används och fungerar.
Fält
Ett statiskt fält är det samma som ett fält som delas mellan alla object av den klassen där det är placerat. Detta betyder att fältet i samliga objekt pekar till samma minnesadress och om en av klasserna ändrar värdet på fältet så kommer det automatiskt att ändras hos samtliga objekt. Låt oss skapa ett enkelt exempel som visar hur det fungerar. Vi kommer att lägga till en räknare i vår klass, som ökas varje gång ett nytt objekt av samma klass skapas. I samma klass lägger vi in en metod som returnerar hur många objekt det finns.
class Order
{
private static int Count = 0;
public Order
{
Count += 1
}
public int GetCount()
{
return Count;
}
}
Vi kommer nu att skapa två olika objekt av klassen Order och skriva ut värdet på fältet vid en rad olika tillfällen för att visa att räknaren ökar automatiskt i båda objekten.
Order a = new Order();
Console.WriteLine( a.GetCount() ); // Skriver ut 1 i ett dos fönster
Order b = new Order();
Console.WriteLine( a.GetCount() ); // Skriver ut 2 I ett dos fönster
Console.WriteLine( b.GetCount() ); // Skriver ut 2 i ett dos fönster
Som ni kan se ökas värdet på Count fältet i objektet a när man skapar objektet b. Detta är pga. som jag sa tidigare, att fältet delar på samma minnesadress.
Metoder
Statiska metoder har en lite annan innebörd än ett statiskt fält. En statisk metod kan man anropa utan att man har tillgång till ett objekt av den klass där metoden befinner sig. Ni behöver inte titta längre än till det förra exemplet där ni ser att jag anropade WriteLine() metoden i klassen Console, vilket inte är ett namn på ett objekt av en klass utan namnet på klassen där WriteLine() metoden finns.Detta är speciellt användbart om man har vissa metoder som man använder väldigt ofta och inte vill behöva ha ett objekt tillgängligt varje gång. Låt oss skapa en enkel matte-klass för att visa hur det skulle gå till att skapa en klass med statiska metoder.
class Math
{
public static int Add(int a, int b)
{
return a+b;
}
public static int Multiply(int a, int b)
{
return a*b;
}
public static int Substract(int a, int b)
{
return a-b;
}
}
Som ni ser har jag valt att inte ha med en metod för att dividera två heltal med varandra. Detta är pga. av att resultatet med största sannolikhet skulle kunna bli ett decimaltal och då skulle jag behöva blanda in kod för att konvertera (type casting) och eftersom jag vill att fokus skall placeras på det faktum att metoderna är statiska så valde jag bort det.
Hur använder vi då våra statiska metoder? Det är enkelt, ta en titt på följande exampel som visar hur man använder samtliga tre metoder i klassen Math utan att ha tillgång till ett objekt av typen Math.
int a = Math.Add(5, 2); // a innehåller nu värdet 7
int b = Math.Multiply(5, 2); // b innehåller nu värdet 10
int c = Math.Subtract(5, 2); // c innehåller nu värdet 3
Även om det inte är helt relaterat till statiska metoder så kan jag nämna att om man har en klass som Math, där man bara har statiska metoder så kan det vara lämpligt att hindra folk från att skapa objekt av denna klass då det inte finns någon vits med det. För att hindra detta behöver vi bara göra en liten modifiering, nämligen att lägga till en privat konstruktor.
class Math
{
private Math()
{
}
public static int Add(int a, int b)
{
return a+b;
}
public static int Multiply(int a, int b)
{
return a*b;
}
public static int Substract(int a, int b)
{
return a-b;
}
}
Eftersom klassen inte innehåller någon publik konstruktor, utan endast en privat så är det omöjligt att skapa ett object av klassen på följande sätt.
Math m = new Math(); // Resulterar i ett fel.
En sista kommentar om statiska metoder är att de inte kan deklareras som abstract, virtual eller override för då kommer man att få ett fel när man prövar att kompilerar.
Attribut
Precis som med statiska metoder, så kan man skapa statiska attribut som man anropar utan att ha tillgång till ett objekt av klassen där attributet befinner sig. Man deklarerar sitt attribut på exakt samma sätt, bara det att man lägger till nyckelordet static i deklarationen.Låt oss bygga ut vår Math klass så att den kan returnera ett versions nummer. Detta nummer kan vara lämpligt att komma åt utan att ha till gång till ett Math objekt så vi deklarerar attributet som statiskt.
class Math
{
private Math()
{
}
public static int Add(int a, int b)
{
return a+b;
}
public static int Multiply(int a, int b)
{
return a*b;
}
public static int Substract(int a, int b)
{
return a-b;
}
public static string Version
{
get { return “1.0.1.1”; }
}
}
För att nu ta reda på vilken version som den befintliga Math versionen är, så kan man helt enkelt göra på följande sätt.
string v = Math.Version; // v innehåller nu versionsnumret 1.0.1.1
Konstruktor
Ibland kan det finnas situationer när man vill att en konstruktor skall anropas innan man anropar någon av de statiska metoderna i en klass. Detta kan t.ex. vara för att sätta vissa startvärde eller liknande saker, innan det att metoden exekveras.För detta finns det statiska konstruktorer. Det är helt enkelt en konstruktor som deklarerats med nyckelordet static. Denna konstruktor anropas när första objektet av klassen skapas eller innan den första statiska metoden exekveras.
Det finns en del begränsningar med statiska konstruktorer som man måste ha i åtanke när man kan deklarerar dem. En statisk konstruktor kan inte:
- Deklareras med en åtkomstmodifierare
- Ta några parametrar
- Anropas direkt
Tyvärr sviktar min fantasi lite här, för att kunna hitta på någon som skulle kunna vara i närheten till ett praktiskt exampel på vad man skulle kunna använda en statisk konstruktor till, så ni får hålla till godo med hur det skulle se ut att lägga till en statisk konstruktor i vår Math klass, som inte gör något. Självklart är tanken med en statisk konstruktor att man skall initiera klassen när en referens till den görs första gången, men med Math klassen finns det inga data att initiera.
class Math
{
private Math()
{
}
static Math()
{
// Denna konstruktor anropas första gången någon av
// de statiska metoderna anropas för första gången, och
// enbart vid första anropet av en statisk metod.
}
public static int Add(int a, int b)
{
return a+b;
}
public static int Multiply(int a, int b)
{
return a*b;
}
public static int Substract(int a, int b)
{
return a-b;
}
public static string Version
{
get { return “1.0.1.1”; }
}
}
0 Kommentarer