Fundamentals of Interfaces

Introduction

An interface is a list of characteristics that can be used to describe an object, but the object must be created from a class of the interface. To create an interface, do as done for a class, but start the name with the letter I. As seen for a class, an interface should be created in a namespace. Here is an example:

namespace Geometry1.Models
{
    public interface IPolygon
    {
    }
}

Implementing an Interface

After creating an interface, you must have a class that implements it. Here is an example:

namespace Geometry1.Models
{
    public interface IPolygon
    {
    }

    public class Triangle : IPolygon
    {
    }
}

After creating a class that implements the interface, the interface is ready to be used.

An Object of an Interface Type

You can declare a variable of an interface. To use the interface object, you need a class that implements that interface. Here is an example:

@{
    IPolygon figure = new EquilateralTriangle();
}

After that, you can use the object.

Interfaces and Methods

In the body of an interface, you can create a method but you can provide only a declaration for that method. Here are examples:

@{
    public interface IPolygon
    {
        // A method in an interface
        double CalculateInscribedRadius();
        
        // Another method
        double CalculateCircumscribedRradius();
    }
}

Because a method cannot be defined in an interface, an interface cannot have a constructor.

A method of an interface can take one or more parameters. When you define that method in a class that implements the interface, you can use or ignore that parameter.

In an interface or a class, you can create a method that returns an object of an interface type.

Interfaces and Properties

An interface can contain a read-only property. Here is an example:

@functions{
    interface IPolygon
    {
        double Area { get; }
    }

    public class Triangle : IPolygon
    {
        public double Area { get; }
    }
}

You can also create a write-only property in an interface and then implement it in a class.

To create a read-write property in an interface, don't use a body on that property. Here are examples:

@functions{
    public interface IVehicle
    {
        int    NumberOfTires { get; set; }
        int    NumberOfDoors { get; set; }
        string Color         { get; set; }
    }
}

In a class that implements that interface, you can create that property as a complete property or as an automatic one.

A Property of an Interface Type

In an interface or a class, you can create a property of an interface type. Here is an example:

Imagine you create an interface as we did above. Here is an example:

@functions{
    public interface IVehicle
    {
        int    NumberOfTires { get; set; }
        int    NumberOfDoors { get; set; }
        string Color         { get; set; }
    }

    public class RentalOrder
    {
        public int InvoiceNumber { get; set; }
    
        public IVehicle Car { get; set; }
    }
}

For an interface-type property, you can access only the members of the interface.

Interfaces and Property Initializers

In an interface, you can create an init property. Here is an example:

@functions{
    public interface IPolygon    
    {
        int Edges         { get; }
        double Side       { get; init; }

        double CalculateInscribedRadius();
    }
}

If you create an init property in an interface, any class that implements that interface must have at least one constructor and you must use that constructor to initialize the property. Here is an example:

@page
@model PracticalLearning.Pages.GeometryModel
@{
    EquilateralTriangle et = new(1336.069);
}

@functions{
    public interface IPolygon
    {
        int Edges         { get; }
        double Side       { get; init; }
        int InternalAngle { get; }
        double Perimeter  { get; }
    }
    
    public class EquilateralTriangle : IPolygon
    {
        public EquilateralTriangle(double edge)
        {
            Side = edge;
        }
        
        public int Edges
        {
            get { return 3; }
        }
        
        public double Side { get; init; }
        
        public int InternalAngle
        {
            get { return 60; }
        }
        
        public double Perimeter
        {
            get { return Side * Edges; }
        }
    }
}

<pre>=================================
Geometry - Equilateral Triangle
---------------------------------
Side:           @et.Side
---------------------------------
Internal Angle: @et.InternalAngle
Perimeter:      @et.Perimeter
=================================</pre>

This would produce:

=================================
Geometry - Equilateral Triangle
---------------------------------
Side:           1336.069
---------------------------------
Internal Angle: 60
Perimeter:      4008.207
=================================

To reduce the code of a class, you can use the => operator on some properties and methods. Here are examples:

@functions{
    public interface IPolygon
    {
        int Edges         { get; }
        double Side       { get; init; }
        int InternalAngle { get; }
        double Perimeter  { get; }
    }
    
    public class EquilateralTriangle : IPolygon
    {
        public EquilateralTriangle(double edge) => Side = edge;
        
        public int Edges => 3;
        
        public double Side { get; init; }
        
        public int InternalAngle => 60;
        public double Perimeter  => Side * Edges;
    }
}

Inheriting an Interface

An interface can be derived from another interface. Here is an example:

@functions{
    interface IPolygon
    {
    }

    interface IPolyhedron : IPolygon
    {
    
    }
}

Implementing Many Interfaces

You can create a class that implements more than one interface. Here is an example:

interface IPolygon
{
}

interface IColorizer
{
}

public class Triangle : IPolygon, IColorizer
{
}

In the same way, you can create a class that implements as many interfaces as you want.

Introduction to Built-In Interfaces

An Interface for the Result of an Action

Formatting a Value

To help you format the primitive values that display in a webpage, the .NET Framework provides the IFormatProvider defined in the System namespace. You can use a class that is equipped with a ToString method. Here are syntaxes of the method:

public string ToString(IFormatProvider provider);
public string ToString(string format)

Here are examples of formatting some values:

@page
@model Valuable.Pages.FormattingValuesModel

@{
    int natural = 13972418;
    double fractional = 13972418.65;

    Console.WriteLine("=============================================");
    Console.WriteLine("Decimal Number Fixed:        {0}", fractional.ToString("f"));
    Console.WriteLine("---------------------------------------------");
    Console.WriteLine("Natural Number Decimal:      {0}", natural.ToString("D"));
    Console.WriteLine("---------------------------------------------");
    Console.WriteLine("Natural Number Currency:     {0}", natural.ToString("c"));
    Console.WriteLine("---------------------------------------------");
    Console.WriteLine("Decimal Number Currency:     {0}", fractional.ToString("c"));
    Console.WriteLine("---------------------------------------------");
    Console.WriteLine("Decimal Number Scientific:   {0}", natural.ToString("e"));
    Console.WriteLine("---------------------------------------------");
    Console.WriteLine("Natural Number Scientific:   {0}", fractional.ToString("e"));
    Console.WriteLine("---------------------------------------------");
    Console.WriteLine("Decimal Number Natural:      {0}", fractional.ToString("n"));
    Console.WriteLine("---------------------------------------------");
    Console.WriteLine("Natural Number Natural:      {0}", natural.ToString("n"));
    Console.WriteLine("---------------------------------------------");
    Console.WriteLine("Decimal Number Natural:      {0}", fractional.ToString("n"));
    Console.WriteLine("---------------------------------------------");
    Console.WriteLine("Natural Number Natural:      {0}", natural.ToString("n"));
    Console.WriteLine("---------------------------------------------");
    Console.WriteLine("Decimal Number General:      {0}", fractional.ToString("g"));
    Console.WriteLine("---------------------------------------------");
    Console.WriteLine("Natural Number Hexadecimal:  {0}", natural.ToString("x"));
    Console.WriteLine("=============================================");
}

<hr />

<pre>Decimal Number Fixed:        @fractional.ToString("f")
---------------------------------------------
Natural Number Decimal:      @natural.ToString("D")
---------------------------------------------
Natural Number Currency:     @natural.ToString("c")
---------------------------------------------
Decimal Number Currency:     @fractional.ToString("c")
---------------------------------------------
Decimal Number Scientific:   @natural.ToString("e")
---------------------------------------------
Natural Number Scientific:   @fractional.ToString("e")
---------------------------------------------
Decimal Number Natural:      @fractional.ToString("n")
---------------------------------------------
Natural Number Natural:      @natural.ToString("n")
---------------------------------------------
Decimal Number Natural:      @fractional.ToString("n")
---------------------------------------------
Natural Number Natural:      @natural.ToString("n")
---------------------------------------------
Decimal Number General:      @fractional.ToString("g")
---------------------------------------------
Natural Number Hexadecimal:  @natural.ToString("x")</pre>

This would produce:

Decimal Number Fixed:        13972418.65
---------------------------------------------
Natural Number Decimal:      13972418
---------------------------------------------
Natural Number Currency:     $13,972,418.00
---------------------------------------------
Decimal Number Currency:     $13,972,418.65
---------------------------------------------
Decimal Number Scientific:   1.397242e+007
---------------------------------------------
Natural Number Scientific:   1.397242e+007
---------------------------------------------
Decimal Number Natural:      13,972,418.65
---------------------------------------------
Natural Number Natural:      13,972,418.00
---------------------------------------------
Decimal Number Natural:      13,972,418.65
---------------------------------------------
Natural Number Natural:      13,972,418.00
---------------------------------------------
Decimal Number General:      13972418.65
---------------------------------------------
Natural Number Hexadecimal:  d533c2

Comparing Two Objects

To assist you in comparing two values or two object, the .NET Framework provides the IComparable created in the System namespace. The class is ready for any primitive type. If you want to compare two objects, you must first implement that insterface for your class. Here is an example:

@functions{
    public class Student : IComparable
    {
        public int     studentNumber;
        public string  firstName;
        public string  lastName;
        public double  age;

        public Student(int number = 0, string first = "John",
                       string last = "Doe", double ag = 1)
        {
            studentNumber = number;
            firstName     = first;
            lastName      = last;
            age           = ag;
        }
        
        public int CompareTo(object obj)
        {
            Student std = (Student)obj;
            
            return std.studentNumber.CompareTo(studentNumber);
        }
    }
}

Here is an example of comparing two Student objects:

@page
@model Valuable.Pages.FormattingValuesModel

@{
    Student std1 = new Student(294759, "Patricia", "Katts", 14.50);
    Student std2 = new Student(294706, "Raymond", "Kouma", 18.50);
    Student std3 = new Student(747747, "Patricia", "Childs", 12.00);
}

@functions{
    public class Student : IComparable
    {
        public int     studentNumber;
        public string  firstName;
        public string  lastName;
        public double  age;

        public Student(int number = 0, string first = "John",
                       string last = "Doe", double ag = 1)
        {
            studentNumber = number;
            firstName     = first;
            lastName      = last;
            age           = ag;
        }
        
        public int CompareTo(object obj)
        {
            Student std = (Student)obj;
            
            return std.studentNumber.CompareTo(studentNumber);
        }
    }
}

<pre>Red Oak High School
-----------------------
Comparison by Student Number
First = Second: @std1.CompareTo(std2)
First = Third:  @std1.CompareTo(std3)
=============================</pre>

This would produce:

Red Oak High School
-----------------------
Comparison by Student Number
First = Second: -1
First = Third:  1
=============================

Disposing of an Object

To assist you in disposing of an object, the .NET Framework provides the IDisposable interface. Many classes that need the service of this interface implement it. As a result, you can use the using operator to apply the services of this interface.

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2001-2023, C# Key Monday 27 December 2021 Next