330 likes | 552 Views
Programmering i C#. 4. Arv och dynamisk bindning. Arv. Härledd klass ska representera något som är en sorts av det basklassen representerar Dimension som inte finns i funktionsorientering Ändrat beteende genom att lägga till ny kod – inte ändra i befintlig
E N D
Programmering i C# 4. Arv och dynamisk bindning
Arv • Härledd klass ska representera något som är en sorts av det basklassen representerar • Dimension som inte finns i funktionsorientering • Ändrat beteende genom att lägga till ny kod – inte ändra i befintlig • Arbetssätt som inte finns i funktionsorientering • Härledd klass kan omdefiniera och utöka • Endast en basklass kan förekomma Programmering i C# - Kapitel 4
Basklass class Shape {int x, y; // positionpublicvoid Move(int x, int y) {this.x += x;this.y += y;}publicdouble Area() {return 0.0;} } Programmering i C# - Kapitel 4
Härledd klass class Circle : Shape {int radius;public Circle(int radius) {this.radius = radius;}publicnewdouble Area() {return System.Math.PI * radius * radius;}publicdouble Circumference() {return System.Math.PI * 2 * radius;} } Programmering i C# - Kapitel 4
Klientkod Shape shp = new Shape(); Console.WriteLine(shp.Area()); // alltid 0.0 Circle cle = new Circle(10); Console.WriteLine(cle.Area()); // 314.15... • Härledd klass metoder och konstruktor kan ej nå koordinaterna! • Är private i basklassen Programmering i C# - Kapitel 4
Synlighet • public – synlig i egna metoder, i härledda klassers metoder och via objekt • private – synlig endast i egna metoder • protected – synlig i egna och härledda klassers metoder • internal – som public, men endast mot klasser i samma assembly • internal protected – kombination Programmering i C# - Kapitel 4
4.1 Arv kontra aggregering • Arv ska endast användas i solklara fall • Kom ihåg: en sorts! • Vid tvekan använd aggregering • Befintliga klassens logik återanvänds genom att ett objekt utgör medlem • Poängen med arv är omdefinitioner och dynamisk bindning Programmering i C# - Kapitel 4
4.2 Konstruktorer och destruktor • Allt ärvs – utom konstruktorer • Utan konstruktoranrop skapas basklassdelen med sin klass defaultkonstruktor • Basklasskonstruktor kan anropas från härledd klass konstruktor • Gör den uppsättning konstruktorer som är relevant i härledda klassen! Programmering i C# - Kapitel 4
Konstruktorer exempel class Shape {int x, y; // positionpublic Shape(int x, int y) // enda konstruktorn{this.x = x;this.y = y;} … Programmering i C# - Kapitel 4
Konstruktorer exempel forts. class Circle : Shape {int radius;public Circle(int x, int y, int radius): base(x, y){this.radius = radius;}public Circle(int radius): base(0, 0){this.radius = radius;}… Programmering i C# - Kapitel 4
Destruktorer • Destruktor anropas automatiskt om sådan finns i aktuell klass eller någon basklass • Basklassens destruktor först • Kan inte anropas explicit • Dispose i basklass bör anropas från härledd klass’ Dispose, om den finns Programmering i C# - Kapitel 4
4.3 Typomvandling • Implicit uppåt – riskabel neråt • Basklassreferens kan ha härlett objekt • Aldrig tvärtom Shape shp = new Shape(100, 100); shp.Move(5, 5); // Shape-objektet flyttas shp = new Circle(100, 100, 50); shp.Move(5, 5); // Circle-objektet flyttas Programmering i C# - Kapitel 4
Två problem • Om basklassreferens refererar till objekt av härledd klass, och: • (1) anropad metod enbart finns i härledda klassen? • (2) anropad metod är omdefinierad i härledda klassen? Programmering i C# - Kapitel 4
Downcast • (1) Referensen måste typomvandlas till objektets typ • Explicit typomvandling genererar undantag • Använd is eller as if (shp is Circle) ((Circle)shp).Circumference(); // eller: Circle cle = shp as Circle; if (cle != null) cle.Circumference(); Programmering i C# - Kapitel 4
Virtuella metoder • (2) Referensens typ avgör vilken klass’ metod som anropas • Statisk bindning • Oftast inte önskvärt – objektets typ bör avgöra val av metod • Dynamisk bindning • Metoden görs virtuell Programmering i C# - Kapitel 4
Virtuell metod, exempel class Shape {...publicdouble Area() {return 0.0:} } class Circle : Shape {...publicnewdouble Area() {return System.Math.PI * radius * radius;} } Programmering i C# - Kapitel 4
4.5 Abstrakta basklasser • Om metoder ska kunna anropas måste de finnas i den basklass som är referensens typ • Kan ofta inte implementeras i basklass • Exempelvis Shape.Area() • Lösning: gör metoden abstract • Klassen blir då också abstrakt – objekt kan inte skapas Programmering i C# - Kapitel 4
Abstrakt klass forts. • Abstrakt metod blir också virtuell • Även egenskaper kan göras abstrakta/virtuella • Härledd klass som inte implementerar alla abstrakta basklassmetoder blir abstrakt abstractclass Shape {...publicabstractdouble Area(); // override i härledd } Programmering i C# - Kapitel 4
4.6 Interface • Ofta bra design samla enbart abstrakta metoder i egen klass • Ger standardiserade interface • Särskild syntax: interface • Tredje kategorin datatyper av tre • Får endast innehålla metoder, egenskaper, indexerare och notifierare • Alla är alltid public Programmering i C# - Kapitel 4
Interface exempel • Medlemmarna är inte virtuella och kan inte markeras virtual! interface IShape {void Move(int x, int y);double Area();int SizeX { get; }int SizeY { get; }... } Programmering i C# - Kapitel 4
Interface forts. • Klass kan implementera flera interface • Implementera == ärva • Samtliga metoder måste implementeras • Samtliga måste vara public, eller deklareras med interfacenamnet • Blir då synliga endast via interfacereferens Programmering i C# - Kapitel 4
Dynamisk bindning från interface • Metoder i interface är inte virtuella • Klass som ärver klass som implementerar ett interface får inte dynamisk bindning • Två lösningar: • Återimplementera interfacet • Mycket excentrisk språkmekanism • Göra implementationerna virtual Programmering i C# - Kapitel 4
Återimplementera interfacet interface IA {void MA(); } class A : IA {publicvoid MA() { ... } } class B : A, IA // upprepad explicit implementation! {publicnewvoid MA() { ... } } Programmering i C# - Kapitel 4
Gör implementationen virtuell interface IA {void MA(); } class A : IA {publicvirtualvoid MA() { ... } // virtuell här! } class B : A {publicoverridevoid MA() { ... } } Programmering i C# - Kapitel 4
Standardinterface • Interface standardiserar vanliga metoder eller grupper av metoder • 19 standardinterface i biblioteket • IDisposable med Dispose() • ICloneable med Clone() • IComparable med CompareTo() Programmering i C# - Kapitel 4
4.7 Arvet från Object • Object är implicit basklass för alla typer • Structer ärver indirekt via ValueType • Har konstruktor – objekt kan skapas • Sällsynta tillfällen • Nio medlemmar varav tre är virtuella metoder som ofta omdefinieras • ToString, GetHashCode och Equals Programmering i C# - Kapitel 4
Object publicclass Object {public Object() {...}~Object() {...}publicvirtualstring ToString() {...}publicvirtualint GetHashCode() {...}publicvirtualbool Equals(object obj) {...}publicstaticbool Equals(object objA, object objB) {...}publicstaticbool ReferenceEquals(object objA, object objB) {...}public Type GetType() {...}protectedobject MemberwiseClone() {...} } Programmering i C# - Kapitel 4
ToString • Bör skapa sträng som beskriver objektet • Medlemmars värden, eventuell ledtext • Basklassversionen ger sträng med typnamnet • Används av bl.a. Console.WriteLine • Bra för spårutskrifter • Kan vara användbart i användarinterface Programmering i C# - Kapitel 4
GetHashCode • Bör returnera stort heltal beroende av objektets tillstånd • Används av Hashtable • Nödvändig om objekt ska läggas i Hashtable • Hashtable kräver också omdefinierad Equals • Basklassversionen returnerar referensens värde (minnesadress) – oanvändbar! Programmering i C# - Kapitel 4
Equals • Två överlagrade: • Virtuell instansmetod • Statisk metod • Instansmetoden bör omdefinieras då objekts tillstånd ska kunna jämföras • Basklassversionen jämför referenserna • Jämför alltså identitet, inte tillstånd Programmering i C# - Kapitel 4
Statiska Equals/ReferenceEquals • Statiska Equals tar två object-referenser • Kontrollerar om någon är null • Kontrollerar om båda är lika • Anropar annars instansmetoden Equals • Statiska ReferenceEquals jämför alltid identitet • Relevant om Equals omdefinierats Programmering i C# - Kapitel 4
Jämförelseoperatorerna • Överlagring av == och != bör också ske om Equals omdefinierats • Enkel implementation: anropa statiska Equals! publicstaticbooloperator==( MyClass objA, MyClass objB) {return Equals(objA, objB); } Programmering i C# - Kapitel 4
MemberwiseClone • Omdefinieras inte • Är en protected hjälpmetod för kopiering av objekt • Kan användas för implementationen av ICloneable.Clone • Ger ”shallow copy” – referenser kopieras • Referenser bör tilldelas nytt objekt Programmering i C# - Kapitel 4