Fundamentals of Inheritance

Introduction

In previous lessons, when we needed a class, we created it, from scratch. If we needed a different class, we created a new one, even if the new class had only slight differeces with an existing class.

If you already have a useful class but need just some extra functionality, instead of creating a different class from scratch, you can still create a new class but you would add only the needed extra functionality. One way you can address this issue is that, in the new class, create a property that uses the existing class as type.

Geometry - Square

Practical LearningPractical Learning: Introducing Inheritance

  1. Start Microsoft Visual Studio
  2. To create a new application, on the main menu, click File -> New -> Project...
  3. In the middle list, make sure Empty Project (.NET Framework) and set the project Name to Geometry03
  4. Click OK
  5. In the Solution Explorer, right-click Geometry03 -> Add -> Class...
  6. In the middle list, make sure Class is selected
    Change the name to Rectangle
  7. Click Add
  8. Change the code as follows:
    namespace Geometry03
    {
        public class Rectangle
        {
            public Rectangle()
            {
                Width  = 0.00;
                Height = 0.00;
            }
    
            public Rectangle(double wide, double high)
            {
                Width = wide;
                Height = high;
            }
    
            public double Width     { get; set; }
            public double Height    { get; set; }
            public double Area      { get { return Width * Height;       } }
            public double Perimeter { get { return (Width + Height) * 2; } }
        }
    }
  9. On the main menu, click Project -> Add -> Class...
  10. In the middle list, make sure Class is selected.
    Change the name to Circle
  11. Click Add
  12. Change the code as follows:
    using System;
    
    namespace Geometry03
    {
        public class Circle
        {
            public Circle()
            {
                Radius = 0.00;
            }
    
            public Circle(double radius)
            {
                Radius = radius;
            }
    
            public double Radius   { get; set; }
            public double Area     => Radius * Radius * Math.PI;
            public double Diameter { get { return Radius * 2; } }
            public double Circumferemce
            {
                get { return Diameter * Math.PI; }
            }
        }
    }
  13. On the main menu, click Project -> Add -> Class...
  14. In the middle list, make sure Class is selected.
    Change the name to Cylinder
  15. Click Add
  16. Change the code as follows:
    namespace Geometry03
    {
        public class Cylinder
        {
            public Cylinder(double radius, double height)
            {
                Base    = new Circle(radius);
                Lateral = new Rectangle(Base.Circumferemce, height);
            }
    
            public Circle    Base    { get; set; }
            public Rectangle Lateral { get; set; }
    
            public double BaseArea    => Base.Area;
            public double LateralArea => Lateral.Area;
            public double Volume      => BaseArea * Lateral.Height;
    
        }
    }
  17. On the main menu, click Project -> Add -> Class...
  18. In the middle list, make sure Class is selected.
    Change the name as Geometry
  19. Click Add
  20. Change the code as follows:
    using static System.Console;
    
    namespace Geometry03
    {
        public class Geometry
        {
            internal static int Main()
            {
                WriteLine("Geometric Shapes - Cylinder");
                WriteLine("---------------------------");
                WriteLine("Enter the following values");
                Write("Radius: ");
                double radius = double.Parse(ReadLine());
                Write("Height: ");
                double height = double.Parse(ReadLine());
    
                Cylinder cyl = new Cylinder(radius, height);
    
                Clear();
    
                WriteLine("Geometric Shapes - Cylinder");
                WriteLine("--------------------------------");
                WriteLine("Radius:          {0}", radius);
                WriteLine("Height:          {0}", height);
                WriteLine("Diameter:        {0}", cyl.Base.Diameter);
                WriteLine("Base Conference: {0}", cyl.Base.Circumferemce);
                WriteLine("Base Area:       {0}", cyl.Base.Area);
                WriteLine("Lateral Area:    {0}", cyl.Lateral.Area);
                WriteLine("Volume:          {0}", cyl.Volume);
                WriteLine("====================================");
    
                return 0;
            }
        }
    }
  21. To execute the application, on the main menu, click Debug -> Start Without Debugging:
    Geometric Shapes - Cylinder
    ------------------
    Enter the following values
    Radius:
  22. For the Radius value, type a decimal number such as 28.86
  23. For the Height value, type a decimal number such as 49.73
    Geometric Shapes - Cylinder
    ---------------------------
    Enter the following values
    Radius: 28.86
    Height: 49.73
  24. Press Enter:
    Geometric Shapes - Cylinder
    --------------------------------
    Radius:          28.86
    Height:          49.73
    Diameter:        57.72
    Base Conference: 181.332727965203
    Base Area:       2616.63126453788
    Lateral Area:    9017.67656170954
    Volume:          130125.072785469
    ====================================
    Press any key to continue . . .
  25. Press Enter to close the window and return to your programming environment
  26. To start a new application, on the main menu of Microsoft Visual Studio, click File -> New -> Project...
  27. In the middle list, click Empty Project (.NET Framework) and set the project Name to Geometry04
  28. Click OK
  29. In the Solution Explorer, right-click Geometry04 -> Add -> Class...
  30. In the middle list, make sure Class is selected.
    Change the Name to Circle
  31. Click Add
  32. Change the document as follows:
    using System;
    
    namespace Geometry04
    {
        class Circle
        {
            double radius;
    
            public Circle()
            {
                radius = 0.00;
            }
    
            public Circle(double rad)
            {
                radius = rad;
            }
    
            public double Radius
            {
                get
                {
                    return radius;
                }
    
                set
                {
                    radius = value;
                }
            }
    
            public double Area     => radius * radius * Math.PI;
            public double Diameter => radius * 2;
            public double Circumferemce
            {
                get { return Diameter * Math.PI; }
            }
        }
    }
  33. In the Solution Explorer, right-click Geometry04 -> Add -> Class...
  34. In the middle list, make sure Class is selected.
    Change the Name to Cylinder
  35. Click Add
  36. Change the class as follows:
    namespace Geometry04
    {
        public class Cylinder
        {
            public double Height { get; set; }
    
            public Cylinder(double baseRadius = 0.00, double height = 0.00)
            {
                Height = height;
            }
    
            public double LateralArea
            {
                get
                {
                    return Circumferemce * Height;
                }
            }
    
            public double Volume
            {
                get
                {
                    return Area * Height;
                }
            }
        }
    }

Introduction to Class Inheritance

Class inheritance is the ability to create a new class that gets its primary functionality from an existing class. Before using inheritance, you must have a class. You can create it like any of the classes we have created so far.

Creating a class that is based on another class is also referred to as deriving a class from another. The first class serves as parent or base. The class that is based on another class is also referred to as child or derived. To create a class based on another, use the following formula:

options class child-class : parent-class
{
    Body of the new class
}

Among the available options, you can start with an access level (public or internal). This is followed by the class keyword and a name for the new class. To indicate that the new class is based on another class, type a colon followed by the name of the base class. For a parent class, you can use one of the .NET Framework built-in classes (but not all classes can be used in inheritance) or you can first create your own class. This means that you must use a class that exists aleady. Here is an example of starting a class inheritance:

public class Circle
{
}

class Cylinder : Circle
{

}

If you want to be able to access the class from other languages, you can precede its name with the public keyword. Here is an example:

public class Circle
{
}

public class Cylinder : Circle
{

}

After deriving a class, it becomes available and you can use it just as you would any other class. Of course, you must first declare a variable for it.

Practical LearningPractical Learning: Deriving From a Class

Inheritance and the Access to Class Members

A Review of Access Levels

When creating a class and when dealing with inheritance, you can control what members can be accessed from outside the class and/or from only inherited members.

As introduced and used in previous lessons, a member of a class is referred to as private if it can be accessed only from within the class. To create a private member variable, type the private keyword to its left. A member variable of a class is internal if it can be accessed by any class of the same project. To create such a member variable, precede it with the internal keyword. A member variable is referred to as public if it can be accessed by the classes of the same file. To create a public member variable of a class, precede it with the public keyword.

The Protected Members of a Class

Besides being made private, a member of a class can be protected to restrict its access. As seen for a private member, a protected member can be accessed by members of the same class. To let you protect a member of a class from non-deriving classes, the C# language provides a keyword named protected. Therefore, to indicate that a member is protected, set its access type to the protected keyword.

The main difference between a private and a protected member is that a protected member can be accessed by the members of its class but also the members of (a) derived class(es). Outside of those two environments, the access to a protected member would produce an error. Both the properties and the methods of a class can be protected.

If you create a member of a class and mark it as protected, the classes derived from its parent class, created in the current project or outside the current project, can access it. If you want the member to be accessed only by derived classes implemented in the same project but not the derived classes outside of the current project, mark the member as protected internal. Here are examples:

public class Person
{
    private string _name;
    private string _gdr;

    public Person(string name = "Not Available",
	              string gender = "Unknown")
    {
    	_name = name;
	    _gdr  = gender;
    }

    protected internal string FullName
    {
    	get { return _name; }
	    set { _name = value; }
    }

    protected internal string Gender
    {
    	get { return _gdr; }
    	set { _gdr = value; }
    }
}

Practical LearningPractical Learning: Protecting a Member of a Class

  1. Access the Circle.cs file and change its class as follows:
    using System;
    
    namespace Geometry04
    {
        public class Circle
        {
            protected double radius;
    
            public Circle()
            {
                radius = 0.00;
            }
    
            public Circle(double rad)
            {
                radius = rad;
            }
    
            public double Radius
            {
                get
                {
                    return radius;
                }
    
                set
                {
                    radius = value;
                }
            }
    
            public double Area     => radius * radius * Math.PI;
            public double Diameter => radius * 2;
            public double Circumferemce
            {
                get { return Diameter * Math.PI; }
            }
        }
    }
  2. Access the Cylinder.cs file and change its class as follows:
    public class Cylinder : Circle
    {
        public double Height { get; set; }
    
        public Cylinder(double baseRadius = 0.00, double height = 0.00)
        {
            radius = baseRadius;
            Height = height;
        }
    
        public double LateralArea
        {
            get
            {
                return Circumferemce * Height;
            }
        }
    
        public double Volume
        {
            get
            {
                return Area * Height;
            }
        }
    }
  3. In the Solution Explorer, right-click Geometry04 -> Add -> Class...
  4. In the middle list, make sure Class is selected.
    Change the Name to Geometry
  5. Click Add
  6. Change the code as follows:
    using static System.Console;
    
    namespace Geometry04
    {
        public class Geometry
        {
            internal static int Main()
            {
                WriteLine("Geometric Shapes - Cylinder");
                WriteLine("---------------------------");
                WriteLine("Enter the following values");
                Write("Radius: ");
                double radius = double.Parse(ReadLine());
                Write("Height: ");
                double height = double.Parse(ReadLine());
    
                Cylinder cyl = new Cylinder(radius, height);
    
                Clear();
    
                WriteLine("Geometric Shapes - Cylinder");
                WriteLine("-------------------------------------");
                WriteLine("Radius:             {0}", radius);
                WriteLine("Height:             {0}", height);
                WriteLine("Diameter:           {0}", cyl.Diameter);
                WriteLine("Base Circumference: {0}", cyl.Circumferemce);
                WriteLine("Base Area:          {0}", cyl.Area);
                WriteLine("Lateral Area:       {0}", cyl.LateralArea);
                WriteLine("Volume:             {0}", cyl.Volume);
                WriteLine("=====================================");
    
                return 0;
            }
        }
    }
  7. To execute the application, on the main menu, click Debug -> Start Without Debugging:
    Geometric Shapes - Cylinder
    ---------------------------
    Enter the following values
    Radius:
  8. For the Radius value, type a decimal number such as 63.97
  9. In the Height text box, type a decimal number such as 117.08
    Geometric Shapes - Cylinder
    ---------------------------
    Enter the following values
    Radius: 63.97
    Height: 117.08
  10. Press Enter:
    Geometric Shapes - Cylinder
    -------------------------------------
    Radius:             63.97
    Height:             117.08
    Diameter:           127.94
    Base Circumference: 401.935364100278
    Base Area:          12855.9026207474
    Lateral Area:       47058.5924288606
    Volume:             1505169.07883711
    =====================================
    Press any key to continue . . .
  11. Press Enter to close the window and return to your programming environment

Characteristics of Inheritance

Partial Class Implementation

In C#, you can create a class (the same class) in different files. This means that you can start a class in one file and continue it in another file or in other files. This is referred to as partial implementation.

As we have seen so far, in C#, you cannot simply and only declare a method in a file for a forward (later) implementation. In C#, to create a class in various files, start the class in one file but precede the class keyword with partial. Here is an example of a file named ResourcesPart.cs that contains some (2) private fields and some (2) properties:

Source File: ResourcesPart.cs
public partial class Person
{
    private string fn;
    private string ln;

    public Person(string first, string last)
    {
        this.ln = last;
        this.fn = first;
    }

    public string FirstName
    {
        get { return fn; }
        set { fn = value; }
    }

    public string LastName
    {
        get { return ln; }
        set { ln = value; }
    }

}

After creating the class in one file, you can use it like any of the classes as we have done so far. Here is an example:

Source File: Exercise.cs
using static System.Console;

public class VaccinationCampaign
{
    public static int Main()
    {
        Person pers = new Person("John", "Foster");

        WriteLine("Personal Identification");
        WriteLine("-----------------------");
        WriteLine("First Name: " + pers.FirstName);
        WriteLine("Last Name:  " + pers.LastName);
        WriteLine("=======================");

        return 0;
    }
}

If you had created a partial class, or you got a partial class from somebody (not as part of a DLL nor from another type of library), and you find out that the class is not complete, you can then complement it. There are rules you must follows:

One of the advantages of partial implementation is that you don't have to get back to the first or previous file to modify it in order to complement the class. You can simply start another file and continue the class in it. Here is an example:

Source File: Human.cs
public partial class Person
{
    private string sex;
    public string DateOfBirth { get; set; }

    public Person(string first, string last, string sex)
    {
        this.sex = sex;
        this.ln = last;
        this.fn = first;
    }

    public string Gender
    {
        get { return sex;  }
        set { sex = value; }
    }
}
Source File: Exercise.cshtml
using static System.Console;

public class VaccinationCampaign
{
    public static int Main()
    {
        Person pers = new Person("John", "Foster", "Male");
        pers.DateOfBirth = "10/04/1986";

        WriteLine("Personal Identification");
        WriteLine("--------------------------");
        WriteLine("First Name:    " + pers.FirstName);
        WriteLine("Last Name:     " + pers.LastName);
        WriteLine("Gender:        " + pers.Gender);
        WriteLine("Date of Birth: " + pers.DateOfBirth);
        WriteLine("==========================");

        return 0;
    }
}

This would produce:

Personal Identification
--------------------------
First Name:    John
Last Name:     Foster
Gender:        Male
Date of Birth: 10/04/1986
==========================
Press any key to continue . . .

Once a partial class has been created, you can create another class based on it. The child class doesn't have to be partial, although it can be.

Namespaces and Inheritance

Imagine you had created a class named Element in a namespace named Chemistry as follows:

namespace Chemistry
{
    public class Element
    {
    }
}

To derive a class from a class that belongs to a namespace, type the name of the namespace, followed by the period operator ".", and followed by the name of the base namespace. Here is an example:

namespace Chemistry
{
    public class Element
    {
    }
}

public class Isotope : Chemistry.Element
{
    public int NeutronNumber { get; set; }
}

If you need to call the class that was defined in a different namespace, you can qualify its name with the period operator. Here is an example:

namespace Chemistry
{
    public class Element
    {
    }
}

public class Isotope : Chemistry.Element
{
    public int NeutronNumber { get; set; }
}

public class Exercise
{
    public void Create()
    {
	Chemistry.Element h = new Chemistry.Element();
    }
}

Alternatively, to use the contents of a namespace, prior to calling a member of that namespace, you can type the using keyword followed by the name of the namespace. Here is an example:

using Chemistry;

public class Isotope : Element
{
    public int NeutronNumber { get; set; }
}

public class Exercise
{
    public void Create()
    {
	Element h = new Element();
    }
}

Consider the following class named Matter and that is created in a nested namespace:

namespace Chemistry
{
    public class Element
    {
    }

    namespace Atoms
    {
        namespace Nucleons
        {
            public class Proton
            {
                public string Symbol { get; set; }
            }

            public class Neutron
            {
            }
        }

        public class Matter
        {
            public double Mass { get; set; }
        }
    }
}

If you want to create a class that is based on a class in a nested namespace, you can qualify its name. Here is an example:

public class Atom : Chemistry.Atoms.Matter
{
    public Chemistry.Element Element { get; set; }
    public Nucleus Nucleus { get; set; }
}

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2001-2019, FunctionX Next