Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Innkapslingen av fornavn- og etternavn-verdiene er representert ved den første klassen, mens de to andre klassene er alternative implementasjoner som støtter denne innkapslingen. Andre klasser bruker bare operasjonene og trenger ikke bry seg om eller gjøre seg avhengig av hvilket alternativ som er valgt. En kan dermed bytte mellom implementasjonsalternativ 1 og 2 uten at andre klasser blir påvirket. Koden

Her er koden for de to alternativene finner du nederst på siden, men prøv selv først!

Synlighetsmodifikatorer

Innkapsling består altså av å definere et sett operasjoner for sikker (og indirekte) tilgang til data, istedenfor å gi direkte tilgang til attributter og dermed lekke detaljer om implementasjonsteknikken til andre klasser. For å gjøre innkapslingen tydelig kan en angi i diagrammer den såkalte synligheten til navn, dvs. hvilke som skal være offentlig (kjent) og hvilke som skal være private. De offentlige skal være mulige å bruke (referere til) utenfor klassen og de private umulige. Dette illustreres med henholdsvis grønne og røde punkter eller + og - foran navnene, som vist i figuren under.

PlantUML Macro
class "Person" as Person1 {
	-String givenName
	-String familyName
	+String getGivenName()
	+void setGivenName(String givenName)
	+String getFamilyName()
	+void setFamilyName(String familyName)
}
note top: Synlighet angitt med grønn og rød farge
PlantUML Macro
skinparam classAttributeIconSize 0
class "Person" as Person2 {
	-String givenName
	-String familyName
	+String getGivenName()
	+void setGivenName(String givenName)
	+String getFamilyName()
	+void setFamilyName(String familyName)
}
note top: Synlighet angitt med + og -

Tilsvarende tilbyr mange objektorienterte språk mekanismer såkalte synlighetsmodifikatorer for å deklarere hvilke navn som skal være offentlige og private. Alternativ 1 over vil kodes som følger:

Code Block
languagejava
titleInnkapsling med bruk av public og private
class Person {
	// private fields
	private String givenName;
	private String familyName;
	// public methods
	public String getGivenName() { ... }
	public void setGivenName(String givenName) { ... }
	public String getFamilyName() { ... }
	public void setFamilyName(String familyName) { ... }
}

Merk at offentlig og privat synlighet kan brukes for både operasjoner og attributter alt ettersom de oppfattes som en del av innkapslingen eller ikke (eller om innkapsling er viktig). Grunnregelen er at alle attributter er private, mens utvalgte operasjoner, de som er en del av innkapslingen, er offentlige. Men det er opp til programmereren å tenke gjennom hvilke som skal brukes hvor.

Til slutt: Koden for de to alternative implementasjonene av Person, den ene med to alternative implementasjonene av Person, navngitt som Person1 og Person2, for å gjøre det enklere å importere dem. Person1 har to String-felt, en for fornavn og en for etternavn, og den andre med mens Person2 har ett String felt for fullt navn. Begge implementerer imidlertid som sagt de samme metodene og kan i praksis erstatte hverandre (bortsett fra konstruktørene).

Code Block
languagejava
collapsetrue
package encapsulation;

public class Person1 {

    private String givenName;
    private String familyName;

    public Person1(String givenName, String familyName) {
        this.givenName = givenName;
        this.familyName = familyName;
    }
    public String getGivenName() {
        return this.givenName;
    }
    public void setGivenName(String givenName) {
        this.givenName = givenName;
    }
    
    public String getFamilyName() {
        return this.familyName;
    }
    public void setFamilyName(String familyName) {
        this.familyName = familyName;
    }
    
    public String getFullName() {
        return this.givenName + " " + this.familyName;
    }
    public void setFullName(String fullName) {
        int pos = fullName.indexOf(' ');
        this.givenName = fullName.substring(0, pos);
        this.familyName = fullName.substring(pos + 1);
    }
}
Code Block
languagejava
collapsetrue
package encapsulation;

public class Person2 {

    private String fullName;

    public Person2(String fullName) {
        this.fullName = fullName;
    }
    public String getFullName() {
        return this.fullName;
    }
    public void setFullName(String fullName) {
        this.fullName = fullName;
    }
    
    public String getGivenName() {
        return this.fullName.substring(0, this.fullName.indexOf(' '));
    }
    public void setGivenName(String givenName) {
        this.fullName = givenName + " " + getFamilyName();
    }
    
    public String getFamilyName() {
        return this.fullName.substring(this.fullName.indexOf(' ') + 1);
    }
    public void setFamilyName(String familyName) {
        this.fullName = getGivenName() + " " + familyName;
    }
}

 

Synlighetsmodifikatorer

Innkapsling består altså av å definere et sett operasjoner for sikker (og indirekte) tilgang til data, istedenfor å gi direkte tilgang til attributter og dermed lekke detaljer om implementasjonsteknikken til andre klasser. For å gjøre innkapslingen tydelig kan en angi i diagrammer den såkalte synligheten til navn, dvs. hvilke som skal være offentlig (kjent) og hvilke som skal være private. De offentlige skal være mulige å bruke (referere til) utenfor klassen og de private umulige. Dette illustreres med henholdsvis grønne og røde punkter eller + og - foran navnene, som vist i figuren under.

PlantUML Macro
class "Person" as Person1 {
	-String givenName
	-String familyName
	+String getGivenName()
	+void setGivenName(String givenName)
	+String getFamilyName()
	+void setFamilyName(String familyName)
}
note top: Synlighet angitt med grønn og rød farge
PlantUML Macro
skinparam classAttributeIconSize 0
class "Person" as Person2 {
	-String givenName
	-String familyName
	+String getGivenName()
	+void setGivenName(String givenName)
	+String getFamilyName()
	+void setFamilyName(String familyName)
}
note top: Synlighet angitt med + og -

Tilsvarende tilbyr mange objektorienterte språk mekanismer såkalte synlighetsmodifikatorer for å deklarere hvilke navn som skal være offentlige og private. Alternativ 1 over vil kodes som følger:

Code Block
languagejava
titleInnkapsling med bruk av public og private
class Person {
	// private fields
	private String givenName;
	private String familyName;
	// public methods
	public String getGivenName() { ... }
	public void setGivenName(String givenName) { ... }
	public String getFamilyName() { ... }
	public void setFamilyName(String familyName) { ... }
}

Merk at offentlig og privat synlighet kan brukes for både operasjoner og attributter alt ettersom de oppfattes som en del av innkapslingen eller ikke (eller om innkapsling er viktig). Grunnregelen er at alle attributter er private, mens utvalgte operasjoner, de som er en del av innkapslingen, er offentlige. Men det er opp til programmereren å tenke gjennom hvilke som skal brukes hvor.