Introduction to Class Inheritance
Introduction to Class Inheritance
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.
Practical Learning: Introducing Inheritance
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; } } } }
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; } } } }
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; } }
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; } } }
Geometric Shapes - Cylinder ------------------ Enter the following values Radius:
Geometric Shapes - Cylinder --------------------------- Enter the following values Radius: 28.86 Height: 49.73
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 . . .
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; }
}
}
}
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 Learning: Deriving From a Class
namespace Geometry04
{
public class Cylinder : Circle
{
. . . No Change
}
}
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 Learning: Protecting a Member of a Class
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; }
}
}
}
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;
}
}
}
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; } } }
Geometric Shapes - Cylinder --------------------------- Enter the following values Radius:
Geometric Shapes - Cylinder --------------------------- Enter the following values Radius: 63.97 Height: 117.08
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 . . .
Characteristics of Inheritance
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 Learning: Ending the Lesson
|
||
Previous | Copyright © 2001-2019, FunctionX | Next |
|