Arv Objektorienterad och komponentbaserad programmering
Arv Regel nr 1: Ett objektorienterat språk ska tillåta inkapsling av data Regel nr 2: Ett objektorienterat språk ska tillåta arv Regel nr 3: Ett objektorienterat språk ska tillåta dynamisk bindning av anrop till metoder Arv innebär att medlemmar i en klass blir tillgängliga i en annan klass Arv är en viktig teknik för att skapa lösningar som är Återanvändbara Förändringsbara Utbyggnadsbara
Arv Via arv kan man skapa hierarkier av klasser som modellerar egenskaper i systemet Varje ärvande klass utvecklas som en specialisering eller utökning av den ärvda klassen Ärvande klass kallas för härledd klass eller subklass Den ärvda klassen kallas för basklass eller superklass
Enkla eller multipla arv I C# så är endast enkla arv tillåtna Det vill säga en klass får endast ärva från en basklass
Åtkomlighet Medlemmar private, endast åtkomlig i den egna klassen internal, endast åtkomlig i en och samma assembly protected, endast åtkomlig via arv och i den egna klassen internal protected, kombination av internal och protected public, fullt åtkomlig utan restriktioner Medlemmar i klasser är default private Klasser public eller internal Klassens åtkomlighet kan begränsa åtkomligheten för dess medlemmar Klasser är default internal Om det i en klass är definierat en inre klass, så gäller samma åtkomstregler för den inre klassen som för övriga medlemmar i den yttre klassen.
Egenskaper kan ärvas i flera led Sådant som är public eller protected i basklassen är synligt via arv Sådant som är internal är endast synligt i en och samma assembly Sådant som är internal protected är fullt synligt i en och samma assembly men endast åtkomligt via arv mellan skilda assemblities
En enkel klass public class Person private string name; protected int ålder; public Person(string namn) //Anropas automatiskt när ett objekt skapas Console.WriteLine("Konstruktor Person"); name = namn; ~Person() //Destruktor, anropas automatiskt när ett objekt upphör att existera Console.WriteLine("Destruktor Person"); public string GetName()return name; //Metoder som så småningom kommer ärvas public void Write() Console.WriteLine("Write - Person: " + GetName()); public void Print() Console.WriteLine("Print - Person: " + GetName());
Klassen provas public class Program public static void Main() Person kalle = new Person("Kalle"); kalle.write(); kalle.print(); //Console.WriteLine( Ålder 0 år, ålder); //ålder ej synligt Konstruktor Person Write - Person: Kalle Print - Person: Kalle Destruktor Person
Ett arv public class Student : Person //Arv från klassen Person public Student(string namn) : base(namn) //OBS! base Console.WriteLine("Konstruktor Student"); ~Student() Console.WriteLine("Destruktor Student"); public new void Print() //new markerar omdefiniering av metoden Console.WriteLine("Print - Student: " + GetName()); public string Namn //En property get return GetName(); //Var är metoden GetName definerad??
Test av arvet public class Program public static void Main() Student stina = new Student("Stina"); stina.write(); stina.print(); OBS => Konstruktor Person Konstruktor Student Write - Person: Stina Print - Student: Stina Destruktor Student Destruktor Person
Referens av basklassen typ public class Program public static void Main() Student stina = new Student("Stina"); stina.write(); stina.print(); Person nisse = new Student("Nils"); nisse.write(); nisse.print(); Det här är ett exempel på statisk bindning av metoder till metodanrop. Metoderna binds till anropen redan vid kompilering och länkning av programmet Det sker med hjälp av referensens typ. OBS => OBS => Konstruktor Person Konstruktor Student Write - Person: Stina Print - Student: Stina Konstruktor Person Konstruktor Student Write - Person: Nils Print - Person: Nils Destruktor Student Destruktor Person Destruktor Student Destruktor Person
Ett arv till! public class Orienterare : Student public Orienterare(string namn) : base(namn) //OBS! base Console.WriteLine("Konstruktor Orienterare"); ~Orienterare() Console.WriteLine("Destruktor Orienterare"); public new void Print() base.print(); //base refererar till basklassen //Console.WriteLine("Print - Orienterare: " + name); Console.WriteLine("Print - Orienterare: " + GetName()); Console.WriteLine("Print Orienterare, ålder: " + ålder);
Ärvs properties? public class Program public static void Main() Orienterare lisa = new Orienterare("Lisa"); lisa.write(); lisa.print(); Console.WriteLine("Namnet är: " + lisa.namn); => Konstruktor Person Konstruktor Student Konstruktor Orienterare Write - Person: Lisa Print - Student: Lisa Print - Orienterare: Lisa Print - Orienterare, ålder: 47 Namnet är: Lisa Destruktor Orienterare Destruktor Student Destruktor Person
is och as, hjälp vid typomvandling av referenser class Program public static void Main() Orienterare lisa1 = new Orienterare("Lisa"); Person lisa2 = lisa1; //Console.WriteLine("Namnet är: " + lisa2.namn); //Varför blir det fel? if (lisa2 is Orienterare) //Är personen lisa2 en orienterare? Console.WriteLine("Namnet är: " + ((Orienterare)lisa2).Namn); Orienterare lisa3 = lisa2 as Orienterare; //Omvandla referensen if (lisa3!= null) //på ett säkert sätt Console.WriteLine("Namnet är: " + lisa3.namn);
Referenser vid arv Det är alltid möjligt att använda en referens av någon basklass-typ Vid statisk bindning så blir endast medlemmar i basklassen åtkomliga via basklassens referens Det är osäkert att använda en referens av en härledd klass på ett objekt av basklassens typ Vad händer om man anropar en metod som endast finns i den härledda klassen?
Design, vilken sorts relation? Test av Arv, Är den härledda klassen en specialisering av basklassen? Är en Student en Person? Är en Cykel ett Fordon? Test av Association, testa om ett objekt bör känna till ett annat objekt Känner hyresgästen till sin lägenhet? Test av Aggregation, testa om en helhet aggregerar delar till sig Har bilen extrahjus? Har studenten ett eller flera betyg? Test av Komposition, testa komponenter, är det frågan om en helhet uppbyggd av delar Är Bilföraren en förare om körkortet upphör att existera? Är Burken fortfarande en burk om dess botten upphör att existera? Komposition är speciell sorts aggregation Aggregation är en speciell sorts association Var försiktig med arv! Om inte testerna tyder på arv så välj en annan typ av relation