A Base Object

Inheritance With the Base Class

When deriving a class, to indicate that you are accessing the parent, you can use the base keyword. That keyword gives a child class access to public and protected members of its parent class.

Practical LearningPractical Learning: Introducing Base Classes

  1. Save the following images to your computer:

    Square

    Square

  2. Start Microsoft Visual Studio. Create a new ASP.NET Core Web App name with Volumetrics2 that supports the .NET 6.0 (Long-Term Support) and uncheck the Configure For HTTPS check box
  3. In the Solution Explorer, right-click Volumetrics2 -> Add -> New Folder
  4. Type Models
  5. In the Solution Explorer, right-click wwwroot -> Add -> New Folder
  6. Type images and press Enter
  7. In the Solution Explorer, under wwwroot, right-click images -> Add -> Existing Item...
  8. Select the images you had saved and Add them to the project
  9. In the Solution Explorer, expand wwwroot
  10. In the Solution Explorer, under wwwroot, right-click css -> Add -> New Item...
  11. In the left list of the Add New Item dialog box, under Visual C#, expand ASP.NET Core. Expand Web, and click Content
  12. In the middle list, click Style Sheet
  13. Change the file Name to Geometry
  14. Press Enter
  15. Change the document as follows:
    body {
    }
    
    .bold        { font-weight:      bold;  }
    .text-right  { text-align:       right  }
    .delimiter   { margin:           auto;
                   width:            650px; }
    .top-bar     { border-bottom:    6px solid blue;
                   background-color: #800000 !important; }
    .common-font { font-family:      Georgia, Garamond, 'Times New Roman', serif; }
    .navbar-light .navbar-brand       { color:       white;  }
    .navbar-light .navbar-brand:hover { color:       yellow; }
    .navbar-light .navbar-brand:focus { color:       khaki;  }
    .navbar-light .navbar-brand       { font-family: Georgia, Garamond, 'Times New Roman', serif; }
    .nav-link                         { font-family: Georgia, Garamond, 'Times New Roman', serif; }
  16. In the Solution Explorer, under Pages, expand Shared
  17. In the Solution Explorer, under Pages and under Shared, double-click _Layout.cshtml
  18. Change the document as follows:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Geometry</title>
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
        <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
        <link rel="stylesheet" href="~/css/Geometry.css" asp-append-version="true" />
    </head>
    <body>
        <header>
            <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3 top-bar">
                <div class="container">
                    <a class="navbar-brand" asp-area="" asp-page="/Index">Geometry</a>
                    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                            aria-expanded="false" aria-label="Toggle navigation">
                        <span class="navbar-toggler-icon"></span>
                    </button>
                    <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                        <ul class="navbar-nav flex-grow-1">
                            <li class="nav-item">
                                <a class="nav-link text-white" asp-area="" asp-page="/Index">Home</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link text-white" asp-area="" asp-page="/Privacy">Privacy</a>
                            </li>
                        </ul>
                    </div>
                </div>
            </nav>
        </header>
        <div class="container">
            <main role="main" class="pb-3">
                @RenderBody()
            </main>
        </div>
    
        <footer class="border-top footer text-muted">
            <div class="container">
                <p class="text-center common-font">&copy; 2022 - Geometry - Volumetrics - <a asp-area="" asp-page="/Privacy">Privacy</a></p>
            </div>
        </footer>
    
        <script src="~/lib/jquery/dist/jquery.min.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    
        @await RenderSectionAsync("Scripts", required: false)
    </body>
    </html>
  19. In the Solution Explorer, right-click Models -> Add -> Class...
  20. In the middle list of the Add New Item dialog box, make sure Class is selected.
    Change the Name of the file to Trapezoid
  21. Click Add
  22. Change the document as follows:
    namespace Volumetrics2.Models
    {
        public class Trapezoid
        {
            public double TopBase    { get; set; }
            public double BottomBase { get; set; }
            public double Height     { get; set; }
    
            public double Area
            {
                get
                {
                    return Height * (TopBase + BottomBase) / 2.00;
                }
            }
        }
    }
  23. In the Solution Explorer, expand Pages and double-click Index.cshtml
  24. Change the document as follows:
    @page
    @model IndexModel
    @using Volumetrics2.Models
    @{
        string? strMessage = null;
        Trapezoid trap = new Trapezoid();
    
        if (Request.HasFormContentType)
        {
            try
            {
                trap.TopBase = double.Parse(Request.Form["txtTopBase"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
    
            try
            {
                trap.BottomBase = double.Parse(Request.Form["txtBottomBase"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
    
            try
            {
                trap.Height = double.Parse(Request.Form["txtHeight"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
        }
    }
    
    <div class="delimiter common-font">
        <h2 class="text-center bold">Geometry - Trapezoid</h2>
        <hr />
       <form name="frmGeometry" method="post">
          <table>
              <tr>
                  <td style="width: 300px" rowspan="9">
                      <img src="~/images/trapezoid1.png" width="296" height="247" alt="Geometry - Trapezoid">
                  </td>
                  <td style="width: 125px" class="bold">Top Base:</td>
                  <td>@Html.TextBox("txtTopBase", @trap.TopBase, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Bottom Base:</td>
                  <td>@Html.TextBox("txtBottomBase", @trap.BottomBase, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Height:</td>
                  <td>@Html.TextBox("txtHeight", @trap.Height, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td>&nbsp;</td>
                  <td style="text-align: center"><input type="submit" name="btnSubmit" value="Calculate" /></td>
              </tr>
              <tr>
                  <td class="bold">Area:</td>
                  <td>@Html.TextBox("txtArea", @trap.Area, new { @class = "form-control text-right" })</td>
              </tr>
          </table>
      </form>
    
      <hr />
      <p class="text-center">@strMessage</p>
    </div>
  25. To execute the project, on the main menu, click Debug -> Start Without Debugging:

    Introducing Read-Write Properties

  26. In the text box, type the following values:
    Top Base:    137.96
    Bottom Base: 209.73
    Height:      87.59

    Introducing Read-Write Properties

  27. Click the Calculate button:

    Introducing Read-Write Properties

  28. Return to your programming environment, press Enter

Practical LearningPractical Learning: Accessing the Base Object from a Child Class

  1. In the Solution Explorer, click-click Models -> Add -> Class...
  2. Type TrapezoidalPrism as the Name of the file
  3. Press Enter
  4. Change the class as follows:
    namespace Volumetrics2.Models
    {
        public class TrapezoidalPrism : Trapezoid
        {
            private double len;
    
            public double Length
            {
                get
                {
                    return len;
                }
    
                set
                {
                    len = value;
                }
            }
    
            public double BaseArea
            {
                get
                {
                    // "base" refers to a parent's property
                    return base.Area;
                }
            }
    
            public double TopArea
            {
                get
                {
                    // "base" TopBase refers to a parent's property
                    return base.TopBase * Length;
                }
            }
    
            public double BottomArea
            {
                get
                {
                    // "base" BottomBase refers to a parent's property
                    return base.BottomBase * Length;
                }
            }
    
            public double Volume
            {
                get
                {
                    // "base" Area refers to a parent's property
                    return base.Area * Length;
                }
    	}
        }
    }
  5. Click the Index.cshtml tab to access the razor page
  6. Change the document as follows:
    @page
    @model IndexModel
    @using Volumetrics2.Models
    @{
        string? strMessage = null;
        TrapezoidalPrism trap = new TrapezoidalPrism();
    
        if (Request.HasFormContentType)
        {
            try
            {
                trap.TopBase = double.Parse(Request.Form["txtTopBase"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
            try
            {
                trap.BottomBase = double.Parse(Request.Form["txtBottomBase"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
            try
            {
                trap.Height = double.Parse(Request.Form["txtHeight"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
            try
            {
                trap.Length = double.Parse(Request.Form["txtLength"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
        }
    }
    
    <div class="delimiter common-font">
        <h2 class="text-center bold">Geometry - Trapezoidal Prism</h2>
        <hr />
       <form name="frmGeometry" method="post">
          <table>
              <tr>
                  <td style="width: 300px" rowspan="9">
                      <img src="~/images/tp.png" width="289" height="230" alt="Geometry - Trapezoidal Prism">
                  </td>
                  <td style="width: 125px" class="bold">Top Base:</td>
                  <td>@Html.TextBox("txtTopBase", @trap.TopBase, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Bottom Base:</td>
                  <td>@Html.TextBox("txtBottomBase", @trap.BottomBase, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Height:</td>
                  <td>@Html.TextBox("txtHeight", @trap.Height, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Length:</td>
                  <td>@Html.TextBox("txtLength", @trap.Length, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td>&nbsp;</td>
                  <td style="text-align: center"><input type="submit" name="btnSubmit" value="Calculate" /></td>
              </tr>
              <tr>
                  <td class="bold">Base Area:</td>
                  <td>@Html.TextBox("txt>BaseArea", @trap.BaseArea, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Top Area:</td>
                  <td>@Html.TextBox("txtTopArea", @trap.TopArea, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Bottom Area:</td>
                  <td>@Html.TextBox("txtBottomArea", @trap.BottomArea, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Volume:</td>
                  <td>@Html.TextBox("txtVolume", @trap.Volume, new { @class = "form-control text-right" })</td>
              </tr>
          </table>
      </form>
    
      <hr />
      <p class="text-center">@strMessage</p>
    </div>
  7. To execute the project, on the main menu, click Debug -> Start Without Debugging:

    Introducing Read-Write Properties

  8. In the text box, type the following values:
    Top Base:    137.96
    Bottom Base: 209.73
    Height:      87.59
    Length:      142.46

    Introducing Read-Write Properties

  9. Click the Calculate button:

    Introducing Read-Write Properties

  10. Return to your programming environment, press Enter

Inheriting the Base Constructors

If a parent class has a constructor, to call that constructor in the child class, you can use the base keyword. The base() constructor must be called immediately after the parentheses of the child constructor. Here is an example:

public class Circle
{
    private double _radius;

    public Circle()
    {
        _radius = 0.00;
    }
}

public class Cone : Circle
{
    private double _height;

    public Cone() : base()
    {
        _height = 0.00;
    }
}

Practical LearningPractical Learning: Inheriting a Base Constructor

  1. Click the Trapezoid.cs tab to access the file
  2. Add a constructor to the class as follows:
    namespace Volumetrics2.Models
    {
        public class Trapezoid
        {
            public double TopBase    { get; set; }
            public double BottomBase { get; set; }
            public double Height     { get; set; }
    
            public Trapezoid(double top, double bottom, double height)
            {
                TopBase    = top;
                BottomBase = bottom;
                Height     = height;
            }
    
            public double Area
            {
                get
                {
                    return Height * (TopBase + BottomBase) / 2.00;
                }
    	}
        }
    }
  3. Click the TrapezoidalPrism.cs tab to access its file
  4. Create a constructor in the class as follows:
    namespace Volumetrics2.Models
    {
        public class TrapezoidalPrism: Trapezoid
        {
            private double len;
    
            public TrapezoidalPrism(double top, double bottom, double height, double length)
                    : base(top, bottom, height)
            {
                Length = length;
            }
    
            . . . No Change
        }
    }
  5. Click the Index.cshtml tab to access the file
  6. Change the code as follows:
    @page
    @model IndexModel
    @using Volumetrics2.Models
    @{
        string? strMessage = null;
        TrapezoidalPrism? trap = null;
    
        if (Request.HasFormContentType)
        {
            double top = 0.00;
            double bottom = 0.00;
            double height = 0.00;
            double length = 0.00;
    
            try
            {
                top = double.Parse(Request.Form["txtTopBase"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
    
            try
            {
                bottom = double.Parse(Request.Form["txtBottomBase"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
    
            try
            {
                height = double.Parse(Request.Form["txtHeight"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
            try
            {
                length = double.Parse(Request.Form["txtLength"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
    
            trap = new TrapezoidalPrism(top, bottom, height, length);
        }
    }
    
    <div class="delimiter common-font">
        <h2 class="text-center bold">Geometry - Trapezoidal Prism</h2>
        <hr />
       <form name="frmGeometry" method="post">
          . . .
      </form>
    
      <hr />
      <p class="text-center">@strMessage</p>
    </div>
  7. To execute the application and test the form, press Ctrl + F5
  8. If the browser presemts a Resend button, click it, or refresh the browser
  9. Change the values in the text boxes as follows:
    Top Base:    588.97
    Bottom Base: 836.84
    Height:      1079.41
    Length:      1326.73
  10. Click the Calculate button:

    Introducing Read-Write Properties

  11. Return to your programming environment

Class Abstraction

Inheritance With this Class

If you create a non-static derived a class, the derived child class has direct access to all public, internal, and protected members of the parent class. You can use the this object to access the members of the parent class.

Practical LearningPractical Learning: Inheriting this Parent

  1. Access the TrapezoidalPrism.cs file and change its class as follows:
    namespace Volumetrics2.Models
    {
        public class TrapezoidalPrism: Trapezoid
        {
            private double len;
    
            public TrapezoidalPrism(double top, double bottom, double height, double length)
                    : base(top, bottom, height)
            {
                // "this" refers to a local property
                this.Length = length;
            }
    
            public double Length
            {
                get
                {
                    // "this" refers to a local field
                    return this.len;
                }
    
                set
                {
                    // "this" refers to a local field
                    this.len = value;
                }
            }
    
            public double BaseArea
            {
                get
                {
                    // "base" refers to a parent
                    return base.Area;
                }
            }
    
            public double TopArea
            {
                get
                {
                    // "this" TopBase refers to a parent's property
                    // "this" refers to a local property
                    return this.TopBase * this.Length;
                }
            }
    
            public double BottomArea
            {
                get
                {
                    // "this" BottomBase refers to a parent's property
                    // "this" refers to a local property
                    return this.BottomBase * this.Length;
                }
            }
    
            public double Volume
            {
                get
                {
                    // "base" Area refers to a parent's property
                    // "this" refers to a local property
                    return base.Area * this.Length;
    	    }
            }
        }
    }
  2. To execute the application and test the form, press Ctrl + F5
  3. If the browser presents a Resend button, click it, or refresh the browser
  4. Change the values in the top text boxes as follows:
    Top Base:    357.93
    Bottom Base: 637.77
    Height:      2263.79
    Length:      975.86
  5. Click the Calculate button:

    Introducing Read-Write Properties

  6. Return to your programming environment
  7. Click the Trapezoid.cs tab to access the file
  8. Change the code of the Area as follows:
    namespace Volumetrics2.Models
    {
        public class Trapezoid
        {
            public double TopBase    { get; set; }
            public double BottomBase { get; set; }
            public double Height     { get; set; }
    
            public Trapezoid(double top, double bottom, double height)
            {
                (TopBase, BottomBase, Height) = (top, bottom, height);
            }
    
            public double Area => Height * (TopBase + BottomBase) / 2.00;
        }
    }
  9. Click the TrapezoidalPrism.cs tab to access its file
  10. Reduce its code as follows:
    namespace Volumetrics2.Models
    {
        public class TrapezoidalPrism : Trapezoid
        {
            private double len;
    
            public TrapezoidalPrism(double top, double bottom, double height, double length)
                    : base(top, bottom, height) => this.Length = length;
    
            public double Length
            {
                get => this.len;
                set => this.len = value;
            }
    
            public double BaseArea
            {
                get => base.Area;
            }
    
            public double TopArea
            {
                get => this.TopBase * this.Length;
            }
    
            public double BottomArea
            {
                get => this.BottomBase * this.Length;
            }
    
            public double Volume
            {
                get => base.Area * this.Length;
            }
        }
    }
  11. To execute the application to test the code and make sure there is no error, press Ctrl + F5
  12. If the browser presents a Resend button, click it, or refresh the browser
  13. Close the browser and return to your programming environment
  14. Save the following images to your computer:

    Square

    Square

  15. Start a new ASP.NET Core Web App named Volumetrics3
  16. In the Solution Explorer, right-click Volumetrics3 -> Add -> New Folder
  17. Type Models
  18. In the Solution Explorer, right-click wwwroot -> Add -> New Folder
  19. Type images and press Enter
  20. In the Solution Explorer, under wwwroot, right-click images -> Add -> Existing Item...
  21. Select the above images you had saved and Add them to the project
  22. In the Solution Explorer, under wwwroot, right-click css -> Add -> New Item...
  23. In the left list of the Add New Item dialog box, under Visual C#, expand ASP.NET Core. Expand Web, and click Content
  24. In the middle list, click Style Sheet
  25. Change the file Name to Geometry
  26. Press Enter
  27. Change the document as follows:
    body {
    }
    
    .bold        { font-weight:      bold;  }
    .text-right  { text-align:       right  }
    .delimiter   { margin:           auto;
                   width:            650px; }
    .top-bar     { border-bottom:    6px solid blue;
                   background-color: navy !important; }
    .common-font { font-family:      Georgia, Garamond, 'Times New Roman', serif; }
    .navbar-light .navbar-brand       { color:       white;  }
    .navbar-light .navbar-brand:hover { color:       yellow; }
    .navbar-light .navbar-brand:focus { color:       khaki;  }
    .navbar-light .navbar-brand       { font-family: Georgia, Garamond, 'Times New Roman', serif; }
    .nav-link                         { font-family: Georgia, Garamond, 'Times New Roman', serif; }
  28. In the Solution Explorer, under Pages, expand Shared
  29. In the Solution Explorer, under Pages and under Shared, double-click _Layout.cshtml
  30. Change the document as follows:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Geometry</title>
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
        <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
        <link rel="stylesheet" href="~/css/Geometry.css" asp-append-version="true" />
    </head>
    <body>
        <header>
            <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3 top-bar">
                <div class="container">
                    <a class="navbar-brand" asp-area="" asp-page="/Index">Geometry</a>
                    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                            aria-expanded="false" aria-label="Toggle navigation">
                        <span class="navbar-toggler-icon"></span>
                    </button>
                    <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                        <ul class="navbar-nav flex-grow-1">
                            <li class="nav-item">
                                <a class="nav-link text-white" asp-area="" asp-page="/Index">Home</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link text-white" asp-area="" asp-page="/Privacy">Privacy</a>
                            </li>
                        </ul>
                    </div>
                </div>
            </nav>
        </header>
        <div class="container">
            <main role="main" class="pb-3">
                @RenderBody()
            </main>
        </div>
    
        <footer class="border-top footer text-muted">
            <div class="container">
                <p class="text-center common-font">&copy; 2022 - Geometry - Volumetrics - <a asp-area="" asp-page="/Privacy">Privacy</a></p>
            </div>
        </footer>
    
        <script src="~/lib/jquery/dist/jquery.min.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    
        @await RenderSectionAsync("Scripts", required: false)
    </body>
    </html>
  31. In the Solution Explorer, right-click Models -> Add -> Class...
  32. In the middle list of the Add New Item dialog box, nake sure Class is selected.
    Set the name of the class as Cylinder
  33. Click Add
  34. Change the class as follows:
    namespace Volumetrics3.Models
    {
        public class Cylinder
        {
            public double Length { get; set; }
            public double Radius { get; set; }
    
            public double Diameter
            {
                get
                {
                    return this.Radius * 2.00;
                }
            }
    
            public double Circumference
            {
                get
                {
                    return this.Diameter * 3.141592653589793238462643;
                }
            }
            
            public double CrossArea
            {
                get
                {
                    return this.Radius * this.Radius * 3.141592653589793238462643;
                }
            }
            
            public double LateralArea
            {
                get
                {
                    return this.Circumference * this.Length;
                }
            }
    
            public double CentralVolume
            {
                get
                {
                    return this.CrossArea * this.Length;
                }
            }
        }
    }
  35. In the Solution Explorer, under Pages, right-click Index.cshtml -> Open
  36. Change the document as follows:
    @page
    @model IndexModel
    @using Volumetrics3.Models
    @{
        string? strMessage = null;
        Cylinder vol = new Cylinder();
    
        if (Request.HasFormContentType)
        {
            try
            {
                vol.Length = double.Parse(Request.Form["txtLength"]);
            }
            catch(FormatException fexc)
            {
                strMessage = "You must provide a valid value for the length (or height)  of the cylinder. " + 
                             Environment.NewLine +
                             "The error produced is: " + fexc.Message;
            }
    
            try
            {
                vol.Radius = double.Parse(Request.Form["txtRadius"]);
            }
            catch(FormatException fexc)
            {
                strMessage = "You must provide a valid value for the radius of the cylinder. " + 
                             Environment.NewLine +
                             "The error produced is: " + fexc.Message;
            }
        }
    }
    
    <div class="delimiter common-font">
        <h2 class="text-center bold">Geometry - Cylinder</h2>
        <hr />
       <form name="frmGeometry" method="post">
          <table>
              <tr>
                  <td style="width: 300px" rowspan="9">
                      <img src="~/images/cylinder.png" width="261" height="281 alt="Geometry - Cylinder">
                  </td>
                  <td style="width: 125px" class="bold">Length:</td>
                  <td>@Html.TextBox("txtLength", @vol.Length, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Radius:</td>
                  <td>@Html.TextBox("txtRadius", @vol.Radius, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td>&nbsp;</td>
                  <td style="text-align: center"><input type="submit" name="btnSubmit" value="Calculate" /></td>
              </tr>
              <tr>
                  <td class="bold">Diameter:</td>
                  <td>@Html.TextBox("txtDiameter", @vol.Diameter, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Circumference:</td>
                  <td>@Html.TextBox("txtCircumference", @vol.Circumference, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Cross Area:</td>
                  <td>@Html.TextBox("txtCrossArea", @vol.CrossArea, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Lateral Area:</td>
                  <td>@Html.TextBox("txtLateralArea", @vol.LateralArea, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Central Volume:</td>
                  <td>@Html.TextBox("txtCentralVolume", @vol.CentralVolume, new { @class = "form-control text-right" })</td>
              </tr>
          </table>
      </form>
    
      <hr />
    
      <p class="text-center">@strMessage</p>
    </div>
  37. To execute the project, on the main menu, click Debug -> Start Without Debugging:

    Introducing Read-Write Properties

  38. In the top text box, type the following values:
    Top Base: 79.84
    Length:   258.93

    Introducing Read-Write Properties

  39. Click the Calculate button:

    Introducing Read-Write Properties

  40. Return to your programming environment, press Z
  41. To add a class, in the Solution Explorer, click Models -> Add -> Class...
  42. Make sure Class is selected in the middle list. Change the name of the file to Tank
  43. Click Add
  44. Change the document as follows:
    namespace Volumetrics3.Models
    {
        public class Tank : Cylinder
        {
            public double Width
            {
                get
                {
                    return this.Diameter;
                }
            }
    
            public double TotalLength
            {
                get
                {
                    return this.Length + this.Radius + this.Radius;
                }
            }
    
            public double TotalArea
            {
                get
                {
                    // Area on one side (half sphere) = Area of Sphere / 2
                    // Areas on both sides = area of a sphere = radius * radius * 4 * PI
                    // Total External Area = lateral area (of the central cylinder) + areas on both sides
                    return this.LateralArea + (this.Radius * this.Radius * PI * 4.00);
                }
            }
    
            public double TotalVolume
            {
                get
            {
                // Volume on one side (half sphere) = Volue of Sphere / 2
                // Volumes on both sides = volume of a sphere = radius * radius * radius * 3.141592653589793238462643 * 4 / 3
                // Total Volume = central volume + volumes on both sides (which is the volume of a sphere)
                return this.CentralVolume + (this.Radius * this.Radius * this.Radius * 3.141592653589793238462643 * 4.00 / 3.00);
            }
        }
    }
  45. Click the Index.cshtml tab
  46. Change the document as follows:
    @page
    @model IndexModel
    @using Volumetrics3.Models
    @{
        string? strMessage = null;
        Tank vol = new Tank();
    
        if (Request.HasFormContentType)
        {
            try
            {
                vol.Length = double.Parse(Request.Form["txtLength"]);
            }
            catch(FormatException fexc)
            {
                strMessage = "You must provide a valid value for the length (or height)  of the cylinder. " + 
                             Environment.NewLine +
                             "The error produced is: " + fexc.Message;
            }
    
            try
            {
                vol.Radius = double.Parse(Request.Form["txtRadius"]);
            }
            catch(FormatException fexc)
            {
                strMessage = "You must provide a valid value for the radius of the cylinder. " + 
                             Environment.NewLine +
                             "The error produced is: " + fexc.Message;
            }
        }
    }
    
    <div class="delimiter common-font">
        <h2 class="text-center bold">Geometry - Tank</h2>
        <hr />
       <form name="frmGeometry" method="post">
          <table>
              <tr>
                  <td style="width: 430px" rowspan="12">
                      <img src="~/images/tank.png" width="428" height="235" alt="Geometry - Tank">
                  </td>
                  <td class="bold">Length:</td>
                  <td>@Html.TextBox("txtLength", @vol.Length, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Radius:</td>
                  <td>@Html.TextBox("txtRadius", @vol.Radius, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td>&nbsp;</td>
                  <td style="text-align: center"><input type="submit" name="btnSubmit" value="Calculate" /></td>
              </tr>
              <tr>
                  <td class="bold">Diameter:</td>
                  <td>@Html.TextBox("txtDiameter", @vol.Diameter, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Circumference:</td>
                  <td>@Html.TextBox("txtCircumference", @vol.Circumference, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Cross Area:</td>
                  <td>@Html.TextBox("txtCrossArea", @vol.CrossArea, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Lateral Area:</td>
                  <td>@Html.TextBox("txtLateralArea", @vol.LateralArea, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Central Volume:</td>
                  <td>@Html.TextBox("txtCentralVolume", @vol.CentralVolume, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Width:</td>
                  <td>@Html.TextBox("txtWidth", @vol.Width, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Total Length:</td>
                  <td>@Html.TextBox("txtTotalLength", @vol.TotalLength, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Total Area:</td>
                  <td>@Html.TextBox("txtTotalArea", @vol.TotalArea, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Total Volume:</td>
                  <td>@Html.TextBox("txtTotalVolume", @vol.TotalVolume, new { @class = "form-control text-right" })</td>
              </tr>
          </table>
      </form>
    
      <hr />
    
      <p class="text-center">@strMessage</p>
    </div>
  47. To execute the project, on the main menu, click Debug -> Start Without Debugging
  48. If the browser presents a Resend button, click it, or refresh the browser:

    Introducing Read-Write Properties

  49. Return to your programming environment
  50. Click the Cylinder.cshtml tab and change its class as follows:
    namespace Volumetrics3.Models
    {
        public class Cylinder
        {
            public double Length { get; set; }
            public double Radius { get; set; }
    
            public double Diameter => this.Radius * 2.00;
            public double Circumference => this.Diameter * 3.141592653589793238462643;
            public double CrossArea => this.Radius * this.Radius * 3.141592653589793238462643;
            public double LateralArea => this.Circumference * this.Length;
            public double CentralVolume => this.CrossArea * this.Length;
        }
    }
  51. Click the Tank.cshtml tab and change the class follows:
    namespace Volumetrics3.Models
    {
        public class Tank : Cylinder
        {
            public double Width
            {
                get => this.Diameter;
            }
    
            public double TotalLength
            {
                get => this.Length + this.Radius + this.Radius;
            }
    
            public double TotalArea
            {
                // Area on one side (half sphere) = Area of Sphere / 2
                // Areas on both sides = area of a sphere = radius * radius * 4 * PI
                // Total External Area = lateral area (of the central cylinder) + areas on both sides
                get => this.LateralArea + (this.Radius * this.Radius * 3.141592653589793238462643 * 4.00);
            }
    
            public double TotalVolume
            {
                // Volume on one side (half sphere) = Volue of Sphere / 2
                // Volumes on both sides = volume of a sphere = radius * radius * radius * 3.141592653589793238462643 * 4 / 3
                // Total Volume = central volume + volumes on both sides (which is the volume of a sphere)
                get => this.CentralVolume + (this.Radius * this.Radius * this.Radius * 3.141592653589793238462643 * 4.00 / 3.00);
            }
        }
    }
  52. To execute again, on the main menu, click Debug -> Start Without Debugging
  53. If the browser presents a Resend button, click it, or refresh the browser
  54. Change the Radius to 279.84
  55. Change the Length to 858.93
  56. Click the Calculate button:

    Introducing Read-Write Properties

  57. Return to your programming environment

The new Modifier

If you create or declare a new member in a derived class and that member has the same name as a member of the base class, when creating the new member, to indicate that that the version of that method is new, use the new keyword.

ApplicationPractical Learning: Creating a New Version of a Member

  1. On the main menu, click File -> Recent Projects and Solutions -> \...\Volumetrics2
  2. Click the TrapezoidalPrism.cs tab and add a new method in the class as follows:
    namespace Volumetrics2.Models
    {
        public class TrapezoidalPrism : Trapezoid
        {
            private double len;
    
            // "this" refers to a local property
            public TrapezoidalPrism(double top, double bottom, double height, double length)
                    : base(top, bottom, height) => this.Length = length;
    
            public double Length
            {
                // "this" refers to a local field
                get => this.len;
    
                // "this" refers to a local field
                set => this.len = value;
            }
    
            public double BaseArea
            {
                // "base" refers to a parent
               get => base.Area;
            }
    
            public double TopArea
            {
                // "this" TopBase refers to a parent's property
                // "this" refers to a local property
                get => this.TopBase * this.Length;
            }
    
            public double BottomArea
            {
                // "this" BottomBase refers to a parent's property
                // "this" refers to a local property
                get => this.BottomBase * this.Length;
            }
    
            public new double Area
            {
                get
                {
                    return BaseArea + TopArea + BottomArea + BaseArea;
                }
            }
    
            public double Volume
            {
                // "base" Area refers to a parent's property
                // "this" refers to a local property
                get => base.Area * this.Length;
            }
        }
    }
  3. Click the Index.cshtml tab to access the razor page
  4. Change the document as follows:
    @page
    @model IndexModel
    @using Volumetrics2.Models
    @{
        string? strMessage = null;
        TrapezoidalPrism trap = new(0.00, 0.00, 0.00, 0.00);
    
        if (Request.HasFormContentType)
        {
            double top    = 0.00;
            double bottom = 0.00;
            double height = 0.00;
            double length = 0.00;
    
            try
            {
                top = double.Parse(Request.Form["txtTopBase"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
    
            try
            {
                bottom = double.Parse(Request.Form["txtBottomBase"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
    
            try
            {
                height = double.Parse(Request.Form["txtHeight"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
            try
            {
                length = double.Parse(Request.Form["txtLength"]);
            }
            catch(FormatException fexc)
            {
                strMessage = fexc.Message;
            }
    
            trap = new(top, bottom, height, length);
        }
    }
    
    <div class="delimiter common-font">
        <h2 class="text-center bold">Geometry - Trapezoidal Prism</h2>
        <hr />
       <form name="frmGeometry" method="post">
          <table>
              <tr>
                  <td style="width: 300px" rowspan="10">
                      <img src="~/images/tp.png" width="296" height="247" alt="Geometry - Trapezoidal Prism">
                  </td>
                  <td style="width: 125px" class="bold">Top Base:</td>
                  <td>@Html.TextBox("txtTopBase", @trap.TopBase, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Bottom Base:</td>
                  <td>@Html.TextBox("txtBottomBase", @trap.BottomBase, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Height:</td>
                  <td>@Html.TextBox("txtHeight", @trap.Height, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Length:</td>
                  <td>@Html.TextBox("txtLength", @trap.Length, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td>&nbsp;</td>
                  <td style="text-align: center"><input type="submit" name="btnSubmit" value="Calculate" /></td>
              </tr>
              <tr>
                  <td class="bold">Base Area:</td>
                  <td>@Html.TextBox("txtArea", @trap.Area, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Top Area:</td>
                  <td>@Html.TextBox("txtTopArea", @trap.TopArea, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Bottom Area:</td>
                  <td>@Html.TextBox("txtBottomArea", @trap.BottomArea, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Total Area:</td>
                  <td>@Html.TextBox("txtArea", @trap.Area, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Volume:</td>
                  <td>@Html.TextBox("txtVolume", @trap.Volume, new { @class = "form-control text-right" })</td>
              </tr>
          </table>
      </form>
    
      <hr />
      <p class="text-center">@strMessage</p>
    </div>
  5. To execute the application, on the menu, click Debug -> Start Without Debugging
  6. Set the values as follows:
    Top Base:    586.77
    Bottom Base: 939.61
    Height:      473.97
    Length:      884.39
  7. Click the Calculate button:

    Introducing Read-Write Properties

  8. To close the window and return to your programming environment, press X
  9. Close your programming environment

The Virtual Members of a Class

When creating a class, if you anticipate that a certain member should be redefined in a derived class, the common member should be created with the virtual keyword. The virtual method can be marked with an access level (private, public, or internal). The virtual keyword can appear before or after the access level.

A property of a class can be made virtual. To create a virtual property, add the virtual keyword before the return type of the property.

Overriding a Member in a Derived Class

After creating a virtual member (method or property) in a class, you can provide a new version of that member in a derived class. This is referred to as overriding the member.

To override a method, in a derived class, create the same method from the parent class. This time, replace the virtual keyword with the override keyword. To override a propertty, create one of the same return type and name in the derived class but use the override keyword instead of the the virtual keyword.

Practical LearningPractical Learning: Introcing Abstraction

  1. Save the following images to your computer:

    Square

    Square

    Square

  2. Start Microsoft Visual Studio. Create a new ASP.NE Core Web App named Quadrilaterals4 that uses the .NET 6.0 (Long-Term Support). Uncheck the Configure For HTTPS check box
  3. In the Solution Explorer, right-click Volumetrics2 -> Add -> New Folder
  4. Type Models
  5. In the Solution Explorer, right-click wwwroot -> Add -> New Folder
  6. Type images and press Enter
  7. In the Solution Explorer, under wwwroot, right-click images -> Add -> Existing Item...
  8. Select the images you had saved and Add them to the project
  9. In the Solution Explorer, expand wwwroot
  10. In the Solution Explorer, under wwwroot, right-click css -> Add -> New Item...
  11. In the left list of the Add New Item dialog box, under Visual C#, expand ASP.NET Core. Expand Web, and click Content
  12. In the middle list, click Style Sheet
  13. Change the file Name to Geometry
  14. Press Enter
  15. Change the document as follows:
    body {
    }
    
    .bold        { font-weight:      bold;  }
    .text-right  { text-align:       right  }
    .delimiter   { margin:           auto;
                   width:            650px; }
    .top-bar     { border-bottom:    6px solid blue;
                   background-color: #800000 !important; }
    .common-font { font-family:      Georgia, Garamond, 'Times New Roman', serif; }
    .navbar-light .navbar-brand       { color:       white;  }
    .navbar-light .navbar-brand:hover { color:       yellow; }
    .navbar-light .navbar-brand:focus { color:       khaki;  }
    .navbar-light .navbar-brand       { font-family: Georgia, Garamond, 'Times New Roman', serif; }
    .nav-link                         { font-family: Georgia, Garamond, 'Times New Roman', serif; }
  16. In the Solution Explorer, under Pages, expand Shared
  17. In the Solution Explorer, under Pages and under Shared, double-click _Layout.cshtml
  18. Change the document as follows:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Geometry</title>
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
        <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
        <link rel="stylesheet" href="~/css/Geometry.css" asp-append-version="true" />
    </head>
    <body>
        <header>
            <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3 top-bar">
                <div class="container">
                    <a class="navbar-brand" asp-area="" asp-page="/Index">Geometry</a>
                    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                            aria-expanded="false" aria-label="Toggle navigation">
                        <span class="navbar-toggler-icon"></span>
                    </button>
                    <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                        <ul class="navbar-nav flex-grow-1">
                            <li class="nav-item">
                                <a class="nav-link text-white" asp-area="" asp-page="/Index">Home</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link text-white" asp-area="" asp-page="/Privacy">Privacy</a>
                            </li>
                        </ul>
                    </div>
                </div>
            </nav>
        </header>
        <div class="container">
            <main role="main" class="pb-3">
                @RenderBody()
            </main>
        </div>
    
        <footer class="border-top footer text-muted">
            <div class="container">
                <p class="text-center common-font">&copy; 2022 - Geometry - <a asp-area="" asp-page="/Privacy">Privacy</a></p>
            </div>
        </footer>
    
        <script src="~/lib/jquery/dist/jquery.min.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    
        @await RenderSectionAsync("Scripts", required: false)
    </body>
    </html>
  19. In the Solution Explorer, right-click Models -> Add -> Class...
  20. In the middle list of the Add New Item dialog box, make sure Class is selected.
    Change the Name of the file to Square
  21. Click Add
  22. Change the document as follows:
    namespace Quadrilaterals4.Models
    {
        public class Square
        {
            public double Side { get; set; }
    
            public Square(double side)
            {
                Side = side;
            }
    
            public double Perimeter
            {
                get
                {
                    return Side * 4.00;
                }
    	}
        }
    }

Practical LearningPractical Learning: Creating Virtual Methods

Practical LearningPractical Learning: Creating a Virtual Property

  1. Create a virtual property in the Square class as follows:
    namespace Quadrilaterals4.Models
    {
        public class Square
        {
            public double Side { get; set; }
    
            public Square(double side)
            {
                Side = side;
            }
    
            public double Perimeter
            {
                get
                {
                    return Side * 4.00;
                }
            }
    
            public virtual double Area
            {
                get
                {
                    return Side * Side;
                }
            }
    
            public virtual double CalculateInradius()
            {
                return Side / 2.00;
    	}
        }
    }
  2. In the Solution Explorer, under Pages, right-click Index.cshtml and click Open
  3. Change the document as follows:
    @page
    @model IndexModel
    @using Quadrilaterals4.Models
    @{
        double length = 0.00;
        string? strMessage = null;
        Square sqr = new Square(0.00);
    
        if (Request.HasFormContentType)
        {
            try
            {
                length = double.Parse(Request.Form["txtSide"])!;
            }
            catch(FormatException fexc)
            {
                strMessage = "You must provide a valid value for the side." + 
                             Environment.NewLine + "The error produced is: " + 
                             fexc.Message;
            }
    
            sqr = new Square(length);
        }
    }
    
    <div class="delimiter common-font">
        <h2 class="text-center bold">Geometry - Square</h2>
        <hr />
       <form name="frmGeometry" method="post">
          <table>
              <tr>
                  <td style="width: 300px" rowspan="5">
                      <img src="~/images/Square2.png" width="483" height="305" alt="Geometry - Square" style="border-right: 1px black solid">
                  </td>
                  <td style="width: 125px" class="bold">Side:</td>
                  <td>@Html.TextBox("txtSide", @sqr.Side, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td>&nbsp;</td>
                  <td style="text-align: center"><input type="submit" name="btnSubmit" value="Calculate" /></td>
              </tr>
              <tr>
                  <td class="bold">Perimeter:</td>
                  <td>@Html.TextBox("txtPerimeter", @sqr.Perimeter, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Area:</td>
                  <td>@Html.TextBox("txtArea", @sqr.Area, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Inradius:</td>
                  <td>@Html.TextBox("txtInradius", @sqr.CalculateInradius(), new { @class = "form-control text-right" })</td>
              </tr>
          </table>
      </form>
    
      <hr />
      <p class="text-center">@strMessage</p>
    </div>
  4. To execute the application to test the webpage, press Ctrl + F5

    Virtual Methods and Properties

  5. Click the Side text box and type 429.63

    Virtual Methods and Properties

  6. Click the Caculate button:

    Virtual Methods and Properties

  7. Return to your programming environment
  8. To create a class, in the Solution Explorer, right-click Models -> Add -> Class...
  9. In the middle list of the Add New Item, make sure Class is selected.
    Change the file Name to Rectangle
  10. Press Enter
  11. Change the class as follows:
    namespace Volumetrics4.Models
    {
        public class Rectangle
        {
            public double Width  { get; set; }
            public double Height { get; set; }
    
            public Rectangle(double width, double height)
            {
                Width = width;
                Height = height;
            }
        }
    }
  12. To create a new class, in the Solution Explorer, right-click Models -> Add -> Class...
  13. Make sure Class is selected in the middle list of the Add New Item dialog box.
    Change the file Name to Box
  14. Click Add
  15. Change the class as follows:
    namespace Volumetrics4.Models
    {
        public class Box : Rectangle
        {
            public Box(double width, double height, double depth)
              : base(width, height)
            {
    	    Depth = depth;
            }
    
            public double Depth { get; set; }
        }
    }

Practical LearningPractical Learning: Overriding a Method in a Derived Class

  1. Click the Rectangle.cs tab and change the class as follows:
    namespace Volumetrics4.Models
    {
        public class Rectangle
        {
            public double Width  { get; set; }
            public double Height { get; set; }
    
            public Rectangle(double width, double height)
            {
                Width  = width;
                Height = height;
            }
    
            public virtual double CalculateArea()
            {
                return Width * Height;
            }
        }
    }
  2. Click the Box.cs tab to access the other class
  3. To override the CalculateArea() method, create a method as follows:
    namespace Volumetrics4.Models
    {
        public class Box : Rectangle
        {
            public Box(double width, double height, double length)
                : base(width, height)
            {
                Length = length;
            }
    
            public double Length { get; set; }
    
            public override double CalculateArea()
            {
                double face = base.CalculateArea();
                double side = base.Height * this.Depth;
                double top  = base.Width  * this.Depth;
    
                return (face * 2) + (side * 2) + (top * 2);
            }
        }
    }
  4. Click the Index.cshtml tab to access the razor page
  5. Change the document as follows:
    @page
    @model IndexModel
    @using Quadrilaterals4.Models
    @{
        string? strMessage = null;
        Box bx = new Box(0.00, 0.00, 0.00);
        double wid = 0.00, hgt = 0.00, dep = 0.00;
    
        if (Request.HasFormContentType)
        {
            try
            {
                wid = double.Parse(Request.Form["txtWidth"])!;
            }
            catch(FormatException fexc)
            {
                strMessage = "You must provide a valid value for the width of the box." + 
                             Environment.NewLine + "The error produced is: " + 
                             fexc.Message;
            }
            try
            {
                hgt = double.Parse(Request.Form["txtHeight"])!;
            }
            catch(FormatException fexc)
            {
                strMessage = "You must provide a valid value for the height of the box." + 
                             Environment.NewLine + "The error produced is: " + 
                             fexc.Message;
            }
            try
            {
                dep = double.Parse(Request.Form["txtDepth"])!;
            }
            catch(FormatException fexc)
            {
                strMessage = "You must provide a valid value for the depth of the box." + 
                             Environment.NewLine + "The error produced is: " + 
                             fexc.Message;
            }
    
            bx = new Box(wid, hgt, dep);
        }
    }
    
    <div class="delimiter common-font">
        <h2 class="text-center bold">Geometry - Rectangular Box</h2>
        <hr />
       <form name="frmGeometry" method="post">
          <table>
              <tr>
                  <td style="width: 300px" rowspan="5">
                      <img src="~/images/Box1.png" width="431" height="279" alt="Geometry - Rectangular Box" style="border-right: 1px black solid">
                  </td>
                  <td style="width: 125px" class="bold">Width:</td>
                  <td>@Html.TextBox("txtWidth", @bx.Width, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Height:</td>
                  <td>@Html.TextBox("txtHeight", @bx.Height, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Depth:</td>
                  <td>@Html.TextBox("txtDepth", @bx.Depth, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td>&nbsp;</td>
                  <td style="text-align: center"><input type="submit" name="btnSubmit" value="Calculate" /></td>
              </tr>
              <tr>
                  <td class="bold">Area:</td>
                  <td>@Html.TextBox("txtArea", @bx.CalculateArea(), new { @class = "form-control text-right" })</td>
              </tr>
          </table>
      </form>
    
      <hr />
      <p class="text-center">@strMessage</p>
    </div>
  6. To execute the application, on the main menu, click Debug -> Start Without Debugging
  7. If the browser presents a Resend button, click it; otherwise refresh the browser:

    Virtual Methods and Properties

  8. Change the values in the text boxes as follows:
    Width:  863.69
    Height: 527.58
    Depth:  1406.97

    Virtual Methods and Properties

  9. Click the Calculate button:

    Virtual Methods and Properties

  10. Close the browser and return to your programming environment

Foundations of Abstract Classes

Introduction

A class is said to be abstract if its primary role is to serve as parent for other classes. To create an abstract class, you use the abstract keyword.Here is an example:

abstract class Triangle
{
}

The desired access level (public or internal) can appear before or after the abstract keyword.

Deriving from an Abstract Class

An abstract class cannot be directly used like a regular class. Instead, you can first create a class derived from the abstract class.

A Parameter of an Abstract Class

When creating a function or method, you can create a parameter whose type is an abstract class. Here is an example:

@page
@model Valuable.Pages.CreatureModel

@functions{
    public abstract class Appliance
    {
        public string? ItemNumber { get; set; }
        public string? Make       { get; set; }
        public string? Model      { get; set; }
        public double  Weight     { get; set; }
        public double  Price      { get; set; }
    }

    double ManageShipping(Appliance machine)
    {
        if (machine.Weight <= 25)
            return 14.95;
        else
            return 24.65;
    }
}

When calling the function or method, the argument you pass must be an object of a class derived from the abstract class. Here is an example:

@page
@model Valuable.Pages.CreatureModel
@{
    Microwave purchase = new();

    purchase.ItemNumber = "NN-CD87KS";
    purchase.Make       = "Panasonic";
    purchase.Model      = "NN-CD87KS";
    purchase.Weight     = 19.1;
    purchase.Price      = 525.95;
}

@functions{
    public abstract class Appliance
    {
        public string? ItemNumber { get; set; }
        public string? Make       { get; set; }
        public string? Model      { get; set; }
        public double  Weight     { get; set; }
        public double  Price      { get; set; }
    }

    public class Microwave : Appliance
    {
        
    }

    public class Refrigerator : Appliance
    {
        public int  Doors    { get; set; }
        public bool IceWater { get; set; }
    }

    double ManageShipping(Appliance machine)
    {
        if (machine.Weight <= 25)
            return 14.95;
        else
            return 24.65;
    }
}

<h1>Appliance Inventory</h1>  

<hr />

<table style="width: 425px" class="table">
    <tr>
        <td style="width: 175px; font-weight: bold">Item #:</td>
        <td>@purchase.ItemNumber</td>
    </tr>
    <tr>
        <td style="font-weight: bold">Make:</td>
        <td>@purchase.Make</td>
    </tr>
    <tr>
        <td style="font-weight: bold">Model:</td>
        <td>@purchase.Model</td>
    </tr>
    <tr>
        <td style="font-weight: bold">Weight:</td>
        <td>@purchase.Weight lbs</td>
    </tr>
    <tr>
        <td style="font-weight: bold">Price:</td>
        <td>@purchase.Price</td>
    </tr>
    <tr>
        <td style="font-weight: bold">Shipping &amp; Handling:</td>
        <td>@ManageShipping(purchase)</td>
    </tr>
</table>

This would produce:

Appliance Inventory
Item #: 	NN-CD87KS
Make: 	Panasonic
Model: 	NN-CD87KS
Weight: 	19.1 lbs
Price: 	525.95
Shipping & Handling: 	14.95

Returning an Object of Abstract Type

You can create a function or method that returns an object of an abstract class. Make sure the function returns an object of that type. Outside the class, when calling the function, you can assign it to a variable of the abstract class. Here is an example:

@page
@model Valuable.Pages.CreatureModel
@{
    Appliance purchase = Create();
}

@functions{
    public abstract class Appliance
    {
        public string? ItemNumber { get; set; }
        public string? Make       { get; set; }
        public string? Model      { get; set; }
        public double  Weight     { get; set; }
        public double  Price      { get; set; }
    }

    public class Microwave : Appliance
    {

    }

    public class Refrigerator : Appliance
    {
        public int  Doors    { get; set; }
        public bool IceWater { get; set; }
    }

    Appliance Create()
    {
        Appliance frigo = new Refrigerator()
        {
            ItemNumber = "284083",
            Make       = "Samsung",
            Model      = "RF23R6201SR",
            Weight     = 279,
            Price      = 1996.85
        };

        return frigo;
    }
}

<h1>Appliance Inventory</h1>  

<hr />

<table style="width: 425px" class="table">
    <tr>
        <td style="width: 175px; font-weight: bold">Item #:</td>
        <td>@purchase.ItemNumber</td>
    </tr>
    <tr>
        <td style="font-weight: bold">Make:</td>
        <td>@purchase.Make</td>
    </tr>
    <tr>
        <td style="font-weight: bold">Model:</td>
        <td>@purchase.Model</td>
    </tr>
    <tr>
        <td style="font-weight: bold">Weight:</td>
        <td>@purchase.Weight lbs</td>
    </tr>
    <tr>
        <td style="font-weight: bold">Price:</td>
        <td>@purchase.Price</td>
    </tr>
</table>

This would produce:

Appliance Inventory
Item #: 	284083
Make: 	Samsung
Model: 	RF23R6201SR
Weight: 	279 lbs
Price: 	1996.85

The Members of an Abstract Class

An Abstract Method

A method is said to be abstract if its class doesn't implement that method but the derived class must implement it. To implement the method, you must apply the override keyword to it.

public class Equilateral : Triangle
{
    readonly double Angle;

    public Equilateral()
    {
        Angle = 60;
    }

    public double Side
    {
        get
        {
            return Base;
        }
    }

    public override double CalculatePerimeter()
    {
        return Side * 3.00;
    }
}

An Abstract Property

A property is abstract if its class doesn't include an implementation of that property. If you want to create an abstract property that has only a get accessor, the property must use the abstract keyword. Here is an example:

public abstract class GeometricFigure
{
    public abstract double Perimeter { get; }
}

If the property has both a get and a set accessors, it can use either the abstract or the virtual keyword.



                

Practical LearningPractical Learning: Introducing Class Abstraction

  1. Start a new ASP.NET Core Web App named GasUtilityCompany1 that uses the .NET 6.0 (Long-Term Support). Uncheck the Configure For HTTPS check box
  2. In the Solution Explorer, right-click GasUtilityCompany1 -> Add -> Folder
  3. Type Models as the name of the folder
  4. In the Solution Explorer, right-click Models -> Add -> Class...
  5. In the middle list of the Add New Item dialog box, make sure Class is selected.
    Change the name to BillPreparation
  6. Click Add
  7. Change the class as follows:
    namespace GasUtilityCompany1.Models
    {
        public class BillPreparation
        {
            public int InvoiceNumber          { get; set; }
            public double CounterReadingStart { get; set; }
            public double CounterReadingEnd   { get; set; }
    
            public double CCFTotal
            {
                get
                {
                    return CounterReadingEnd - CounterReadingStart;
                }
            }
    
            public double TotalTherms
            {
                get
                {
                    return CCFTotal * 1.0367;
                }
            }
    
            public double DistributionAdjustment
            {
                get
                {
                    return TotalTherms * 0.13086;
                }
            }
    
            public double CalculateTransportationCharges()
            {
                if (TotalTherms <= 5000)
                    return TotalTherms * 0.016289;
                else
                    return TotalTherms * 0.009577;
            }
    
            public double CalculateDeliveryTotal()
            {
                double first50Therms = 0, over50Therms = 0;
    
                if (TotalTherms < 5000)
                {
                    first50Therms = TotalTherms * 0.05269;
                    over50Therms = 0;
                }
                else
                {
                    first50Therms = 5000 * 0.5269;
                    over50Therms = (TotalTherms - 5000) * 0.04995;
                }
    
                return CalculateTransportationCharges() + DistributionAdjustment + first50Therms + over50Therms;
            }
    
            public double EnvironmentalCharges
            {
                get
                {
                    return CalculateDeliveryTotal() * 0.0045;
                }
            }
    
            public double AmountDue
            {
                get
                {
                    return CalculateDeliveryTotal() + EnvironmentalCharges;
                }
    	    }
        }
    }
  8. In the Solution Explorer, expand wwwroot
  9. In the Solution Explorer, under wwwroot, right-click css -> Add -> New Item...
  10. In the Add New Item dialog box, click Style Sheet
  11. Change the file Name to GasUtilityCompany
  12. Press Enter
  13. Change the document as follows:
    body {
    }
    
    .bold                             { font-weight:      bold;  }
    .text-right                       { text-align:       right; }
    .delimiter                        { margin:           auto;
                                        width:            450px; }
    .top-bar                          { border-bottom:    6px solid blue;
                                        background-color: #005CB9 !important; }
    .navbar-light .navbar-brand       { color:            white;
                                        font-weight:      bold;   }
    .navbar-light .navbar-brand:hover { color:            yellow;
                                        font-weight:      bold;   }
    .navbar-light .navbar-brand:focus { color:            khaki;
                                        font-weight:      bold;   }
    .navbar-light .navbar-brand       { font-family:      Garamond, Georgia, 'Times New Roman', serif; }
    .nav-link                         { font-weight:      bold;
                                        font-family:      Garamond, Georgia, 'Times New Roman', serif; }
    .common-font                      { font-family:      Garamond, Georgia, 'Times New Roman', serif; }
  14. In the Solution Explorer, expand Pages and expand Shared
  15. In the Solution Explorer, under Pages and under Shared, double-click _Layout.cshtml
  16. Change the document as follows:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>@ViewData["Title"] - Gas Utility Company</title>
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
        <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
        <link rel="stylesheet" href="~/css/GasUtilityCompany.css" asp-append-version="true" />
    </head>
    <body>
        <header>
            <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3 top-bar">
                <div class="container">
                    <a class="navbar-brand" asp-area="" asp-page="/Index">Gas Utility Company</a>
                    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                            aria-expanded="false" aria-label="Toggle navigation">
                        <span class="navbar-toggler-icon"></span>
                    </button>
                    <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                        <ul class="navbar-nav flex-grow-1">
                            <li class="nav-item">
                                <a class="nav-link text-white" asp-area="" asp-page="/Index">Home</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link text-white" asp-area="" asp-page="/Privacy">Privacy</a>
                            </li>
                        </ul>
                    </div>
                </div>
            </nav>
        </header>
        <div class="container">
            <main role="main" class="pb-3">
                @RenderBody()
            </main>
        </div>
    
        <footer class="border-top footer text-muted">
            <div class="container">
                <p class="text-center common-font">&copy; 2022 - Gas Utility Company - <a asp-area="" asp-page="/Privacy">Privacy</a></p>
            </div>
        </footer>
    
        <script src="~/lib/jquery/dist/jquery.min.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    
        @await RenderSectionAsync("Scripts", required: false)
    </body>
    </html>
  17. In the Solution Explorer, under Pages, right-click Index.cshtml -> Open
  18. Change the document as follows:
    @page
    @model IndexModel
    @using GasUtilityCompany1.Models
    @{
        string? strMessage = null;
        BillPreparation bp = new();
        string strAmountDue = "0.00";
        string strTotalTherms = "0.00";
        string strDeliveryTotal = "0.00";
        string strEnvironmentalCharges = "0.00";
        string strTransportationCharges = "0.00";
        string strDistributionAdjustment = "0.00";
    
        if (Request.HasFormContentType)
        {
            Random rndNumber = new();
    
            bp.InvoiceNumber = rndNumber.Next(100000, 999999);
    
            try
            {
                bp.CounterReadingStart = double.Parse(Request.Form["txtCounterReadingStart"])!;
            }
            catch(FormatException fexc)
            {
                strMessage = "You must provide a valid value for the counter reading start value." + 
                             Environment.NewLine + "The error produced is: " + 
                             fexc.Message;
            }
            try
            {
                bp.CounterReadingEnd = double.Parse(Request.Form["txtCounterReadingEnd"])!;
            }
            catch(FormatException fexc)
            {
                strMessage = "You must provide a valid value for the counter reading end value." + 
                             Environment.NewLine + "The error produced is: " + 
                             fexc.Message;
            }
    
            strAmountDue              = $"{bp.AmountDue:F}";
            strTotalTherms            = $"{bp.TotalTherms:F}";
            strDeliveryTotal          = $"{bp.CalculateDeliveryTotal():F}";
            strEnvironmentalCharges   = $"{bp.EnvironmentalCharges:F}";
            strDistributionAdjustment = $"{bp.DistributionAdjustment:F}";
            strTransportationCharges  = $"{bp.CalculateTransportationCharges():F}";
        }
    }
    
    <div class="delimiter common-font">
        <h2 class="text-center bold">Gas Utility Company</h2>
        <hr />
        <h5 class="text-center bold">Customer Invoice Preparation</h5>
        <hr />
        <form name="frmGeometry" method="post">
            <table>
                <tr>
                    <td style="width: 250px" class="bold">Invoice Number:</td>
                    <td>@Html.TextBox("txtInvoiceNumber", @bp.InvoiceNumber, new { @class = "form-control text-right" })</td>
                </tr>
                <tr>
                    <td class="bold">Counter Reading Start:</td>
                    <td>@Html.TextBox("txtCounterReadingStart", @bp.CounterReadingStart, new { @class = "form-control text-right" })</td>
                </tr>
                <tr>
                    <td class="bold">Counter Reading End:</td>
                    <td>@Html.TextBox("txtCounterReadingEnd", @bp.CounterReadingEnd , new { @class = "form-control text-right" })</td>
                </tr>
                <tr>
                    <td>&nbsp;</td>
                    <td style="text-align: center"><input type="submit" name="btnSubmit" value="Calculate" /></td>
                </tr>
            </table>
        </form>
          
        <hr />
          
        <h4 class="bold">Gas Meter Reading</h4>
          
        <hr />
    
        <table>
            <tr>
                <td class="bold" style="width: 250px">Invoice Number:</td>
                <td>@Html.TextBox("txtInvoiceNumber", @bp.InvoiceNumber, new { @class = "form-control text-right" })</td>
            </tr>
            <tr>
                <td class="bold">Counter Reading Start:</td>
                <td>@Html.TextBox("txtCounterReadingStart", @bp.CounterReadingStart, new { @class = "form-control text-right" })</td>
            </tr>
            <tr>
                <td class="bold">Counter Reading End:</td>
                <td>@Html.TextBox("txtCounterReadingEnd", @bp.CounterReadingEnd, new { @class = "form-control text-right" })</td>
            </tr>
            <tr>
                <td class="bold">CCF Total:</td>
                <td>@Html.TextBox("txtCCFTotal", @bp.CCFTotal, new { @class = "form-control text-right" })</td>
            </tr>
            <tr>
                <td class="bold">Total Therms:</td>
                <td>@Html.TextBox("txtTotalTherms", @strTotalTherms, new { @class = "form-control text-right" })</td>
            </tr>
            <tr>
                <td class="bold">Distribution Adjustment:</td>
                <td>@Html.TextBox("txtDistributionAdjustment", @strDistributionAdjustment, new { @class = "form-control text-right" })</td>
            </tr>
          </table>
          
          <hr />
          
          <h5 class="bold">Bill Values</h5>
          
          <hr />
    
          <table>
              <tr>
                  <td style="width: 250px" class="bold">Transportation Charges:</td>
                  <td>@Html.TextBox("txtTransportationCharges", @strTransportationCharges, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Delivery Total:</td>
                  <td>@Html.TextBox("txtDeliveryTotal", @strDeliveryTotal, new { @class = "form-control text-right" })</td>
              </tr>
              <tr>
                  <td class="bold">Environmental Charges:</td>
                  <td>@Html.TextBox("txtEnvironmentalCharges", @strEnvironmentalCharges, new { @class = "form-control text-right" })</td>
              </tr>
          </table>
          
          <hr />
    
          <table>
              <tr>
                <td class="bold" style="width: 250px">Amount Due:</td>
                  <td>@Html.TextBox("txtAmountDue", @strAmountDue, new { @class = "form-control text-right" })</td>
              </tr>
          </table>
    
      <hr />
      <p class="text-center">@strMessage</p>
    </div>
  19. To execute the application to test it, on the main menu, click Debug -> Start Without Debugging:

    Virtual Methods and Properties

  20. Click the Counter Reading Start text box and type 214485
  21. Click the Counter Reading End text box and type 215057

    Virtual Methods and Properties

  22. Click the Calculate button:

    Virtual Methods and Properties

  23. Return to your programming environment
  24. In the Solution Explorer, right-click the Models -> Add -> Class...
  25. In the Add New Item dialog, make sure Class is selected. Change the name to CustomerInvoice
  26. Click Add:
    namespace GasUtilityCompany1.Models
    {
        public class CustomerInvoice
        {
        }
    }

Practical LearningPractical Learning: Creating an Abstract Class

  1. Click the BillPreparation.cs tab to accesss the file
  2. Between the public and the class keywords, type the abstract keyword (the other changes are optional):
    namespace GasUtilityCompany1.Models
    {
        public abstract class BillPreparation
        {
            public int InvoiceNumber          { get; set; }
            public double CounterReadingStart { get; set; }
            public double CounterReadingEnd   { get; set; }
    
            public double CCFTotal
            {
                get => CounterReadingEnd - CounterReadingStart;
            }
    
            public double TotalTherms
            {
                get => CCFTotal * 1.0367;
            }
    
            public double DistributionAdjustment
            {
                get => TotalTherms * 0.13086;
            }
    
            public double CalculateTransportationCharges()
            {
                return (TotalTherms <= 5000) ? (TotalTherms * 0.016289) : (TotalTherms * 0.009577);
            }
    
            public double CalculateDeliveryTotal()
            {
                double first50Therms = 0, over50Therms = 0;
    
                if (TotalTherms < 5000)
                {
                    first50Therms = TotalTherms * 0.05269;
                    over50Therms = 0;
                }
                else
                {
                    first50Therms = 5000 * 0.5269;
                    over50Therms = (TotalTherms - 5000) * 0.04995;
                }
    
                return CalculateTransportationCharges() + DistributionAdjustment + first50Therms + over50Therms;
            }
    
            public double EnvironmentalCharges
            {
                get => CalculateDeliveryTotal() * 0.0045;
            }
    
            public double AmountDue
            {
                get => CalculateDeliveryTotal() + EnvironmentalCharges;
            }
        }
    }
  3. To execute, on the main menu, click Debug -> Start Without Debugging
  4. Notice that you recieve an error. Read the text in the message box and click No. Read the error in the bottom window

Practical LearningPractical Learning: Deriving from an Abstract Class

  1. Click the CustomerInvoice.cs tab to access the other class
  2. Derive the CustomerInvoice class from the BillPreparation class as follows:
    public class CustomerInvoice : BillPreparation
    {
    }

Practical LearningPractical Learning: Deriving from an Abstract Class

  1. Click the Index.cshtml tab to access its file
  2. Change the declaration of the class variable as follows:
    @page
    @model IndexModel
    @using GasUtilityCompany1.Models
    @{
        string? strMessage = null;
        BillPreparation bp = new CustomerInvoice();
        string strAmountDue = "0.00";
        string strTotalTherms = "0.00";
        string strDeliveryTotal = "0.00";
        string strEnvironmentalCharges = "0.00";
        string strTransportationCharges = "0.00";
        string strDistributionAdjustment = "0.00";
    
        if (Request.HasFormContentType)
        {
            . . .
        }
    }
    
    <div class="delimiter common-font">
        <h2 class="text-center bold">Gas Utility Company</h2>
        <hr />
        <h5 class="text-center bold">Customer Invoice Preparation</h5>
        <hr />
        
        . . .
    
      <hr />
      <p class="text-center">@strMessage</p>
    </div>
  3. To execute the application to test it, on the main menu, click Debug -> Start Without Debugging
  4. Change the Counter Reading Start to 6921
  5. Change the Counter Reading End to 9248
  6. Click the Calculate button:

    Virtual Methods and Properties

  7. Return to your programming environment

A Sealed Class

Introduction

A class is said to be sealed if new classes cannot be derived from that class.

Sealing a Class

To create a sealed class, use the sealed keyword. Here are examples:

sealed public class TimeWorked
{

}

public sealed class WorkingTime
{

}

A derived class can also be sealed. Here is an example:

public abstract class Triangle
{
}

sealed public class Irregular : Triangle
{
}

A Sealed Method

If you use the sealed keyword to create a class, the whole class becomes sealed, but you may not want the whole class to be sealed. Sometimes, you may want only some members to be sealed.

If you create a new method in a derived class, you cannot seal it. Therefore, before sealing a method, you must first create it in class. You must mark that method as abstract or virtual.

A Sealed Property

A property from a class can be sealed. Before creating a sealed property, its class must be derived from another class. Before sealing a property, you must mark the property in the derived class as override. To seal a property, type the sealed keyword close to the override keyword. The sealed keyword can appear before or after override.

Static Classes

When a class has been made static, no class can be derived from it. This means that when you create a static class, it becomes automatically sealed.

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2001-2023, C# Key Saturday 17 December 2022 Next