Inheritance
Build new classes from existing ones: base and derived classes, the is-a rule, base constructors, protected members and sealed.
public class StructuralMember // base class (parent){ public string Mark { get; set; } = ""; public string Material { get; set; } = "S355"; public double Length { get; set; } public string Describe() => $"{Mark}: {Material}, {Length} m";} public class Beam : StructuralMember // derived class (child){ public string Profile { get; set; } = "IPE200";} public class Column : StructuralMember{ public bool IsBraced { get; set; }} var b = new Beam { Mark = "B1", Length = 6, Profile = "IPE300" };Console.WriteLine(b.Describe()); // inherited methodConsole.WriteLine(b.Profile); // its own propertyB1: S355, 6 m IPE300
class Beam : StructuralMember reads “Beam inherits from StructuralMember”. A Beam automatically has everything public and protected that StructuralMember has, plus what it adds itself.
The is-a rule
StructuralMember m = new Beam { Mark = "B2" }; // OK: a Beam is a memberConsole.WriteLine(m.Describe());// Console.WriteLine(m.Profile); // error: through m we only see member things StructuralMember[] frame = { new Beam(), new Column(), new Beam() }; // mix them in one arrayConstructors and base(...)
: base(...). The base constructor always runs before the derived one.
public class StructuralMember{ public string Mark { get; } public StructuralMember(string mark) { Mark = mark; Console.WriteLine($"StructuralMember({mark})"); }} public class Beam : StructuralMember{ public string Profile { get; } public Beam(string mark, string profile) : base(mark) // pass mark up { Profile = profile; Console.WriteLine($"Beam({profile})"); }} var b = new Beam("B7", "HEA240");StructuralMember(B7) Beam(HEA240)
protected: for children only
public class StructuralMember{ protected double SelfWeightKn; // children may use it, outside code may not} public class Beam : StructuralMember{ public double TotalLoad(double liveKn) => SelfWeightKn + liveKn; // OK}Rules and limits
A class can inherit from only one base class (single inheritance). Interfaces, coming soon, cover the “many” case. Every class ultimately inherits from object, which is why everything hasToString(),Equals()andGetType().Mark a class sealedto stop others from inheriting from it:public sealed class Bolt.Private members of the base exist in the object but can’t be used by the derived class’s code.
Shape with a Name property and a constructor that takes the name. Derive Circle (Radius) and Square (Side) that pass their names to the base constructor and each add a method double Area(). Create one of each and print name and area.
Show the solution
public class Shape{ public string Name { get; } public Shape(string name) => Name = name;} public class Circle : Shape{ public double Radius { get; } public Circle(double r) : base("Circle") => Radius = r; public double Area() => Math.PI * Radius * Radius;} public class Square : Shape{ public double Side { get; } public Square(double s) : base("Square") => Side = s; public double Area() => Side * Side;} var c = new Circle(1);var s = new Square(3);Console.WriteLine($"{c.Name}: {c.Area():F2}");Console.WriteLine($"{s.Name}: {s.Area()}");Circle: 3.14 Square: 9
Remember
class Child : Parentreuses and extends the parent’s members.Inherit only for true is-a relationships; prefer composition for has-a. Base constructors run first; pass arguments with : base(...).Single inheritance only; every class derives from object;sealedstops inheritance.