Skip to content

Information hiding

Information hiding är när man gömmer intern data i klassen, så att den inte kan användas på fel sätt eller utanför den egna instansen. Låt oss säga att vi har en klass som har ett attribut som innehåller någon känslig data. Då vill vi inte att det ska gå att använda den datan hur som helst. Vi vill kanske kontrollera hur värdet sätts, göra en speciell uträkning för att få ett nytt värde, eller så är bara värdet hemligt. Vi vill kunna begränsa tillgången till variabler eller metoder utanför klassdefinitionen.

Det finns tre olika klassificeringar inom klassisk objektorientering: publik, skyddad och privat. Publika variabler används sällan i objektorienterad programmering. Oftast är variablerna privata och nås med publika get- och set-metoder. Det finns också skyddade variabler och metoder som endast subklasser (tas upp i samband med arv) kommer åt.

ImplementationTypSyfte
public namepublik (public)Kan nås av vem som helst.
protected _nameskyddad (protected)Funkar som privat men metoden/variabeln kan också nås från klasser som ärver från klassen där de deklareras
private _nameprivat (private)Nås endast från klassen där den deklareras (default om inget annat anges)

Anledning till att använda privata attribut

Section titled “Anledning till att använda privata attribut”

Vi använder privata attribut för att:

  • skydda klassens data
  • för att ha en kontrollerad och säker åtkomst till klassens data
  • för att dölja implementeringen av klassen
  • minska risken för att klassens data används på ett felaktigt sätt

Helst bör alla klassens variabler vara privata och därför ändrar vi WHEELS till privat. Det är praxis att konstanter har namn med versaler (stora bokstäver) även om de är privata.

Gör medlemsvariablerna i klassen Car privata
namespace OoGuide.src;
class Car
{
private const int WHEELS = 4;
private static int _carCount = 0;
...
}

Om vi nu anropar WHEELS som vi gjorde innan blir det kompileringsfel.

Testkör koden från introduktions kapitlet
// Console.WriteLine("Antal hjul: " + Car.WHEELS);
// Ger kompileringsfelet: error CS0122: 'Car.Wheels' is inaccessible due to its protection level

För att få tillgång till innehållet i WHEELS kan vi göra en getmetod, vilket vi gör i nästa kapitel.

Nu har vi gömt alla variabler inuti Car klassen och tillfört metoder för den tillgång och bearbetning som ska tillåtas. Detta kallas för information hiding.

I klassen RaceTrack är redan alla variabler privata och gömda och vi tittar över metoderna. Metoden PrintFinishLine kan delas upp i två metoder, en privat som heter PrintFinishLine (denna kan alltså inte anropas utifrån) och en publik som heter Description. Description ska skriva ut information om racerbanan och anropar PrintFinishLine som hanterar en specifik del av det som ska ingå i utskriften.

Koden kan då se ut så här:

Uppdatera koden i klassen RaceTrack
namespace OoGuide.src;
class RaceTrack
{
private const string NAME = "DBWEBB Racing track";
...
// Other methods
public void Description()
{
Console.WriteLine($"\nVälkommen till {RaceTrack.NAME}!");
this.PrintFinishLine();
}
private void PrintFinishLine()
{
string spaces = new string(' ', this._finishLine);
Console.WriteLine(string.Concat("\nSTART", spaces.AsSpan(0, spaces.Length - 6), "MÅL"));
Console.WriteLine(spaces + "|");
}
}

Eftersom metoden PrintFinishLine är privat kan den endast användas inuti klassen RaceTrack.

Testkör koden genom att anropa den privata metoden PrintFinishLine
RaceTrack track1 = new RaceTrack(100);
track1.PrintFinishLine();
// Ger kompileringsfelet: error CS0122: 'RaceTrack.PrintFinishLine()' is inaccessible due to its protection level

Och det vi får detta bekräftat eftersom vi gjorde den privat för att använda dne internt inom klassen.

Testkör koden genom att anropa den publika metoden Description
RaceTrack track1 = new RaceTrack(100);
track1.Description();

Det funkar bra och vi får ut en beskrivning samt en mållinje.

Vi lägger utskrifterna från detta kapitel och förra i en publik funktion (vilken i sin tur anropar en privat metod). Nu ser det ut så här:

Strukturera koden genom att lägga den i en metod som anropas i Program.cs
...
static void TestingPrivatePrintouts()
{
//Console.WriteLine("Antal hjul: " + Car.WHEELS);
// Ger kompileringsfelet: error CS0122: 'Car.GetWheels()' is inaccessible due to its protection level
RaceTrack track1 = new RaceTrack(100);
//track1.PrintFinishLine();
// Ger kompileringsfelet: error CS0122: 'RaceTrack.PrintFinishLine()' is inaccessible due to its protection level
track1.Description();
}
TestingPrivatePrintouts();

När vi inte vill använda metoden TestingPrivatePrintouts kommenterar vi bort den.