A Sealed Class

Introduction

A sealed class is a class that cannot serve as a base class in inheritance. That is, you cannot derive a class from a sealed class.

Practical LearningPractical Learning: Introducing Static Classes

  1. Start Microsoft Visual Studio. Create a new Console App named PayrollPreparation7 that uses the .NET 8.0 (Long-Term Support)
  2. To create a new folder, in the Solution Explorer, right-click PayrollPreparation7 -> Add -> New Folder
  3. Type Models as the name of the folder
  4. In the Solution Explorer, right-click Models -> Add -> Class...
  5. Change the file Name to Calculations
  6. Click Add
  7. Start two classes as follows:
    namespace PayrollPreparation7.Models
    {
        internal class Calculations
        {
        }
    
        internal class Operations
        {
        }
    }

Static Classes

As seen previously, a static class is a class marked with the static keyword and whose all members are static. 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: Creating a Static Class

  1. Change the class as follows:
    namespace PayrollPreparation7.Models
    {
        internal static class Calculations
        {
            public static double Add(double a, double b)
            {
                return a + b;
            }
    
            public static double Add(double a, double b, double c, double d, double e)
            {
                return a + b + c + d + e;
            }
    
            public static double Subtract(double a, double b)
            {
                return a - b;
            }
    
            public static double Multiply(double a, double b)
            {
                return a * b;
            }
        }
    }
  2. In the Solution Explorer, right-click Models -> Add -> Class...
  3. Change the file name to Payroll
  4. Click Add
  5. Start two classes by typing the following code:
    namespace PayrollPreparation7.Models
    {
        internal class Payroll
        {
        }
    
        internal class TimeSheet : Payroll
        {
        }
    }

Sealing a Class

A regular class, that is, a non-static class, can be sealed so it would not act as a base class for another class. To get a sealed class, you use a keyword named sealed. Therefore, to seal a class, type the sealed keyword to the left of the class keyword.

If the class is marked with an access modifier, the sealed keyword can appear before or after the access modifier. Here are examples:

sealed public class TimeWorked
{

}

public sealed class WorkingTime
{

}

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

public abstract class Triangle
{
}

sealed public class Irregular : Triangle
{
}

Remember that once a class is sealed, it cannot serve as a parent of another class. As an alternative, the class can be used to create a property in another class that would use it as a pseudo-parent.

Practical LearningPractical Learning: Creating a Sealed Class

  1. In the Payroll.cs file, to create a sealed class, type the following word:
    namespace PayrollPreparation7.Models
    {
        internal sealed class Payroll
        {
        }
    
        internal class TimeSheet : Payroll
        {
        }
    }
  2. To execute the application, on the main menu, click Debug -> Start Without Debugging
  3. You should receive an error (read the message of the error):
    Severity	Code	Description	Project	File	Line	Suppression State
    Error	CS0509	'TimeSheet': cannot derive from sealed type 'Payroll'	PayrollPreparation1	. . .
  4. Change the class as follows:
    namespace PayrollPreparation7.Models
    {
        internal sealed class Payroll
        {
            private double timeSpecified;
    
            public Payroll(double salary, double time)
            {
                HourlySalary = salary;
                timeSpecified = time;
            }
    
            public double HourlySalary { get; set; }
    
            public double OvertimeSalary
            {
                get { return Calculations.Multiply(HourlySalary, 1.50); }
            }
    
            public double RegularTime
            {
                get
                {
                    if (timeSpecified <= 40.00)
                        return timeSpecified;
                    else
                        return 40.00;
                }
            }
    
            public double Overtime
            {
                get
                {
                    if (timeSpecified <= 40.00)
                        return 0.00;
                    else
                        return Calculations.Subtract(timeSpecified, 40.00);
                }
            }
    
            public double RegularPay
            {
                get { return Calculations.Multiply(HourlySalary, RegularTime); }
            }
    
            public double OvertimePay
            {
                get { return Calculations.Multiply(OvertimeSalary, Overtime); }
            }
    
            public double NetPay
            {
                get { return Calculations.Add(RegularPay, OvertimePay); }
            }
        }
    }
  5. In the Solution Explorer, right-click Program.cs and click Rename
  6. Type PayrollPreparation (to get PayrollPreparation.cs) and press Enter
  7. Read the message box and click Yes
  8. Click the PayrollPreparation.cs tab and change the document as follows:
    using static System.Console;
    using PayrollPreparation7.Models;
    
    double salary    = 0.00;
    double monday    = 0.00;
    double tuesday   = 0.00;
    double wednesday = 0.00;
    double thursday  = 0.00;
    double friday    = 0.00;
    
    try
    {
        WriteLine("Payroll Preparation");
        WriteLine("===================================================");
        WriteLine("You provide the values to evalue your payroll");
    
        Write("Hourly Salary: ");
        salary = double.Parse(ReadLine()!);
    }
    catch (FormatException fe)
    {
        WriteLine("The value you entered for the hourly salary is not valid.");
        WriteLine("The error produced is:");
        WriteLine(fe.Message);
    }
    
    try
    {
        WriteLine("--------------------------------------------------");
        WriteLine("Provide the time worked for each day of the week");
        WriteLine("--------------------------------------------------");
        Write("Monday:        ");
        monday = double.Parse(ReadLine()!);
    }
    catch (FormatException fe)
    {
        WriteLine("The value you entered for the time worked on Monday is not valid.");
        WriteLine("The error produced is:");
        WriteLine(fe.Message);
    }
    
    try
    {
        Write("Tuesday:       ");
        tuesday = double.Parse(ReadLine()!);
    }
    catch (FormatException fe)
    {
        WriteLine("The value you entered for the time worked on Tuesday is not valid.");
        WriteLine("The error produced is:");
        WriteLine(fe.Message);
    }
    
    try
    {
        Write("Wednesday:     ");
        wednesday = double.Parse(ReadLine()!);
    }
    catch (FormatException fe)
    {
        WriteLine("The value you entered for the time worked on Wednesday is not valid.");
        WriteLine("The error produced is:");
        WriteLine(fe.Message);
    }
    
    try
    {
        Write("Thursday:      ");
        thursday = double.Parse(ReadLine()!);
    }
    catch (FormatException fe)
    {
        WriteLine("The value you entered for the time worked on Thursday is not valid.");
        WriteLine("The error produced is:");
        WriteLine(fe.Message);
    }
    
    try
    {
        Write("Friday:        ");
        friday = double.Parse(ReadLine()!);
    }
    catch (FormatException fe)
    {
        WriteLine("The value you entered for the time worked on Friday is not valid.");
        WriteLine("The error produced is:");
        WriteLine(fe.Message);
    }
    
    double totalTime = Calculations.Add(monday, tuesday, wednesday, thursday, friday);
    
    Payroll preparation = new Payroll(salary, totalTime);
    
    WriteLine("==================================================");
    WriteLine("Payroll Summary");
    WriteLine("==================================================");
    WriteLine("Hourly Salary: {0}", preparation.HourlySalary);
    WriteLine("-------+---------+-----------+----------+---------");
    WriteLine("Monday | Tuesday | Wednesday | Thursday | Friday");
    WriteLine("-------+---------+-----------+----------+---------");
    WriteLine(" {0,5:f} |   {1,4:f}  | {2,7:f}   |  {3,5:f}   | {4,5:f}",
                      monday, tuesday, wednesday, thursday, friday);
    WriteLine("=======+=========+===========+==========+========" +
                "=");
    WriteLine("                    Regular Time:  {0,8:f}", preparation.RegularTime);
    WriteLine("--------------------------------------------------");
    WriteLine("                    Overtime:      {0,8:f}", preparation.Overtime);
    WriteLine("--------------------------------------------------");
    WriteLine("                    Regular Pay:   {0,8:f}", preparation.RegularPay);
    WriteLine("--------------------------------------------------");
    WriteLine("                    Overtime Pay:  {0,8:f}", preparation.OvertimePay);
    WriteLine("--------------------------------------------------");
    WriteLine("                    Total Pay:     {0,8:f}", preparation.NetPay);
    WriteLine("==================================================");
  9. To execute the application, on the main menu, click Debug -> Start Without Debugging
  10. When requested, type the Hourly Salary as 26.75 and press Enter
  11. For the days work, type the numbers as follows and press Enter after each value:
    Monday:    8
    Tuesday:   9.5
    Wednesday: 8
    Thursday:   10.5
    Friday:      8.5
    Payroll Preparation
    ===================================================
    You provide the values to evalue your payroll
    Hourly Salary: 26.75
    --------------------------------------------------
    Provide the time worked for each day of the week
    --------------------------------------------------
    Monday:        8
    Tuesday:       9.5
    Wednesday:     8
    Thursday:      10.5
    Friday:        8.5
    ==================================================
    Payroll Summary
    ==================================================
    Hourly Salary: 26.75
    -------+---------+-----------+----------+---------
    Monday | Tuesday | Wednesday | Thursday | Friday
    -------+---------+-----------+----------+---------
      8.00 |   9.50  |    8.00   |  10.50   |  8.50
    =======+=========+===========+==========+=========
                        Regular Time:     40.00
    --------------------------------------------------
                        Overtime:          4.50
    --------------------------------------------------
                        Regular Pay:    1070.00
    --------------------------------------------------
                        Overtime Pay:    180.56
    --------------------------------------------------
                        Total Pay:      1250.56
    ==================================================
    
    Press any key to close this window . . .
  12. Return to your programming environment
  13. Click the Calculations.cs tab to access the file
  14. Change the class as follows:
    public static class Calculations
    {
        public static double Add(double a, double b) => a + b;
    
        public static double Add(double a,
                                 double b,
                                 double c,
                                 double d,
                                 double e) => a + b + c + d + e;
    
        public static double Subtract(double a, double b) => a - b;
        public static double Multiply(double a, double b) => a * b;
    }
  15. Click the Payroll.cs tab to access the file
  16. Change the document as follows:
    namespace PayrollPreparation7.Models
    {
        internal sealed class Payroll
        {
            private double timeSpecified;
    
            public Payroll(double salary, double time)
            {
                HourlySalary = salary;
                timeSpecified = time;
            }
    
            public double HourlySalary { get; set; }
    
            public double OvertimeSalary => Calculations.Multiply(HourlySalary, 1.50);
    
            public double RegularTime
            {
                get
                {
                    return (timeSpecified <= 40.00) ? timeSpecified : 40.00;
                }
            }
    
            public double Overtime
            {
                get
                {
                    return (timeSpecified <= 40.00) ? 0.00 : Calculations.Subtract(timeSpecified, 40.00);
                }
            }
    
            public double RegularPay
            {
                get => Calculations.Multiply(HourlySalary, RegularTime);
            }
    
            public double OvertimePay
            {
                get => Calculations.Multiply(OvertimeSalary, Overtime);
            }
    
            public double NetPay
            {
                get => Calculations.Add(RegularPay, OvertimePay);
            }
        }
    }
  17. Click the PayrollPreparation.cs tab to access the file
  18. Change the document as follows:
    using static System.Console;
    using PayrollPreparation7.Models;
    
    double salary    = 0.00;
    double monday    = 0.00,
           tuesday   = 0.00,
           wednesday = 0.00,
           thursday  = 0.00,
           friday    = 0.00;
    
    try
    {
        WriteLine("Payroll Preparation");
        WriteLine("===================================================");
        WriteLine("You provide the values to evalue your payroll");
    
        Write("Hourly Salary: ");
        salary = double.Parse(ReadLine()!);
    }
    catch(Exception ex) when (ex is FormatException fe)
    {
        WriteLine("The value you entered for the hourly salary is not valid.");
        WriteLine("The error produced is:");
        WriteLine(fe.Message);
    }
    
    try
    {
        WriteLine("--------------------------------------------------");
        WriteLine("Provide the time worked for each day of the week");
        WriteLine("--------------------------------------------------");
        Write("Monday:        ");
        monday = double.Parse(ReadLine()!);
    }
    catch(Exception ex) when (ex is FormatException fe)
    {
        WriteLine("The value you entered for the time worked on Monday is not valid.");
        WriteLine("The error produced is:");
        WriteLine(fe.Message);
    }
    
    try
    {
        Write("Tuesday:       ");
        tuesday = double.Parse(ReadLine()!);
    }
    catch(Exception ex) when (ex is FormatException fe)
    {
        WriteLine("The value you entered for the time worked on Tuesday is not valid.");
        WriteLine("The error produced is:");
        WriteLine(fe.Message);
    }
    
    try
    {
        Write("Wednesday:     ");
        wednesday = double.Parse(ReadLine()!);
    }
    catch(Exception ex) when (ex is FormatException fe)
    {
        WriteLine("The value you entered for the time worked on Wednesday is not valid.");
        WriteLine("The error produced is:");
        WriteLine(fe.Message);
    }
    
    try
    {
        Write("Thursday:      ");
        thursday = double.Parse(ReadLine()!);
    }
    catch(Exception ex) when (ex is FormatException fe)
    {
        WriteLine("The value you entered for the time worked on Thursday is not valid.");
        WriteLine("The error produced is:");
        WriteLine(fe.Message);
    }
    
    try
    {
        Write("Friday:        ");
        friday = double.Parse(ReadLine()!);
    }
    catch(Exception ex) when (ex is FormatException fe)
    {
        WriteLine("The value you entered for the time worked on Friday is not valid.");
        WriteLine("The error produced is:");
        WriteLine(fe.Message);
    }
    
    Payroll preparation = new Payroll(salary, Calculations.Add(monday, tuesday, wednesday, thursday, friday));
    
    WriteLine("==================================================");
    WriteLine("Payroll Summary");
    WriteLine("==================================================");
    WriteLine("Hourly Salary: {0}", preparation.HourlySalary);
    WriteLine("-------+---------+-----------+----------+---------");
    WriteLine("Monday | Tuesday | Wednesday | Thursday | Friday");
    WriteLine("-------+---------+-----------+----------+---------");
    WriteLine(" {0,5:f} |   {1,4:f}  | {2,7:f}   |  {3,5:f}   | {4,5:f}",
                      monday, tuesday, wednesday, thursday, friday);
    WriteLine("=======+=========+===========+==========+========" +
                "=");
    WriteLine("                    Regular Time:  {0,8:f}", preparation.RegularTime);
    WriteLine("--------------------------------------------------");
    WriteLine("                    Overtime:      {0,8:f}", preparation.Overtime);
    WriteLine("--------------------------------------------------");
    WriteLine("                    Regular Pay:   {0,8:f}", preparation.RegularPay);
    WriteLine("--------------------------------------------------");
    WriteLine("                    Overtime Pay:  {0,8:f}", preparation.OvertimePay);
    WriteLine("--------------------------------------------------");
    WriteLine("                    Total Pay:     {0,8:f}", preparation.NetPay);
    WriteLine("==================================================");
  19. To execute and make sure there is no error, on the main menu, click Debug -> Start Without Debugging
  20. Close the window and return to your programming environment

Characteristics of a Sealed Class

A Sealed Method

If you use the sealed keyword on 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.

One of the charateristics of inheritance is that a derived class can provide a behavior of a parent's method. This can be done by overriding a method of the parent. Sometimes when creating a non-sealed class, you may want to prevent the deriving class(es) from overriding a certain method. In this case, you can seal the method. A sealed method is a function that doesn't allow deriving classes to override it.

If you create a new method in a derived class, that is, a method that does not exist in the parent class, you cannot seal it. This means that you can seal only a method that can be overridden. Therefore, before sealing a method, you must first create it in class. You must mark that method as abstract or virtual.

Remember that, in a derived class, you must override every parent's abstract or virtual method. To seal a method, in the derived class, precede the return type by the sealed keyword. The sealed keyword can appear before or after override. Here are examples:

using System;

public abstract class RoundShape
{
    public virtual  double Radius { get; set; }
    public abstract double Diameter { get; }
}

public class Circle : RoundShape
{
    private double rad;

    public sealed override double Radius // sealed before override
    {
        get
        {
            return this.rad;
        }

        set
        {
            this.rad = value;
        }
    }

    public override sealed double Diameter // override before sealed = same thing
    {
        get
        {
            return this.rad * 2;
        }
    }
}

A Sealed Property

A property from a class A is said to be sealed if no class B deriving from class A is allowed to provide a new version of the property.

As seen for a method, before creating a sealed property, its class must be derived from another class. Here is an example of such as class created as abstract:

public abstract class RoundShape
{
    public virtual  double Radius { get; set; }
    public abstract double Diameter { get; }
}

Of course, you must derive a class from such as class. Before sealing a property, you must override it from the parent class. That is, 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.

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2002-2024, FunctionX Sunday 30 April 2023, 14:06 Next