C#-Classes.. Contd

Polymorphism and Overriding Methods

“Many forms” is what polymorphism refers to, and it happens when there are numerous classes that are connected to one another through inheritance. We can inherit properties and methods from another class through inheritance, as we explained in the previous chapter. These techniques are used by polymorphism to carry out various functions. This gives us the ability to carry out a single activity in multiple ways. Consider a base class called Animal, for instance, which contains the animalSound() function. Pigs, cats, dogs, and birds are examples of derived classes of animals. They also have their own unique ways of making animal sounds, such as pig oinks and cat meows, among others:

Example

class Animal  // Base class (parent)
  {
    public void animalSound()
    {
      Console.WriteLine(“The animal makes a sound”);
      }
}
class pig  : Animal  // Derived class (child)
{
  public void animalSound( )
  {
    Console.WriteLine(“The pig says: wee wee”);
  }
}
class Dog : Animal   //  Derived  class (child)
{
  public void animalSound()
{
Console.WriteLine(“The dog says: bow wow”);
 }
}
At this point, we can make Pig and Dog objects and use the animalSound() function on each of them:

Example

  class Animal  // Base class (parent)
  {
    public void animalSound()
    {
      Console.WriteLine(“The animal makes a sound”);
    }
  }
  class Pig : Animal  // Derived class (child)
  {
    public void animalSound()
    {
      Console.WriteLine(“The pig says: wee wee”);
    }
  }
  class Dog : Animal  // Derived class (child)
  {
    public void animalSound()
    {
      Console.WriteLine(“The dog says: bow wow”);
    }
  }
  class Program
  {
    static void Main(string[] args)
    {
      Animal myAnimal = new Animal();  // Create a Animal object
      Animal myPig = new Pig();  // Create a Pig object
      Animal myDog = new Dog();  // Create a Dog object
      myAnimal.animalSound();
      myPig.animalSound();
      myDog.animalSound();
    }
  }
}
The output  will be:
The animal makes a sound
The animal makes a sound
The animal makes a sound
Not The Output I Was Looking For
You most likely did not anticipate the results from the aforementioned case. This is due to the fact that when two methods have the same name, the base class method takes precedence. Nevertheless, C# offers the ability to override the base class method by use the override keyword for each derived class method and by adding the virtual keyword to the method inside the base class:

Example

class Animal  // Base class (parent)
  {
    public virtual void animalSound()
    {
      Console.WriteLine(“The animal makes a sound”);
    }
  }
  class Pig : Animal  // Derived class (child)
  {
    public override void animalSound()
    {
      Console.WriteLine(“The pig says: wee wee”);
    }
  }
  class Dog : Animal  // Derived class (child)
  {
    public override void animalSound()
    {
      Console.WriteLine(“The dog says: bow wow”);
    }
  }
  class Program
  {
    static void Main(string[] args)
    {
      Animal myAnimal = new Animal();  // Create a Animal object
      Animal myPig = new Pig();  // Create a Pig object
      Animal myDog = new Dog();  // Create a Dog object
      myAnimal.animalSound();
      myPig.animalSound();
      myDog.animalSound();
    }
  }
The output will be:
The animal makes a sound
The pig says : wee wee
The dog says: bow bow

Why And When To Use “Inheritance” and “Polymorphism”?

Reusing fields and methods from an existing class when creating a new one is helpful for code reusability.

Abstract Classes and Methods

Data abstraction is the process of just displaying pertinent information to the user and hiding other details. Either abstract classes or interfaces—more on which in the upcoming chapter—can be used to accomplish abstraction. For classes and methods, using the abstract keyword:
  • An abstract class must be inherited from another class in order to access it; it is a limited class that cannot be used to construct objects.
  • Abstract methods don’t have bodies and can only be used in abstract classes. The derived class (inherited from) provides the body.
Both regular and abstract methods are possible in an abstract class:
abstract class Animal
{
 public abstract void animalSound( );
 public void sleep()
{
   Console.WriteLine(“Zzz”);
}
}
It is impossible to build an object of the Animal type using the example above:
Animal myObj  = new Animal(); // Will generate an error (Cannot create an instance of the abstract class or interface ‘Animal’)
 
The abstract class needs to be inherited from another class in order to be accessible. Let’s create an abstract class based on the Animal class we used in the Polymorphism chapter.

As you recall from the Inheritance chapter, to inherit from a class, use the : symbol; to override the base class method, use the override keyword.

Example

// Abstract class
  abstract class Animal
  {
    // Abstract method (does not have a body)
    public abstract void animalSound();
    // Regular method
    public void sleep()
    {
      Console.WriteLine(“Zzz”);
    }
  }
  // Derived class (inherit from Animal)
  class Pig : Animal
  {
    public override void animalSound()
    {
      // The body of animalSound() is provided here
      Console.WriteLine(“The pig says: wee wee”);
    }
  }
  class Program
  {
    static void Main(string[] args)
    {
      Pig myPig = new Pig();  // Create a Pig object
      myPig.animalSound();
      myPig.sleep();
    }
  }

Why And When To Use Abstract Classes and Methods?

To ensure security, only display an object’s most crucial features and conceal others. Note: Interfaces, about which you will read more in the following chapter, can also be used to achieve abstraction.

Interfaces

Using interfaces is another method in C# for achieving abstraction. An interface can only have abstract methods and attributes (with empty bodies), making it a fully “abstract class”:

Example

  // interface
interface Animal
{
  void animalSound( );    // interface method (does not have a body)
  void run( );  // interface method (does not have a body)
}
Starting an interface with the letter “I” is generally accepted as best practice since it helps both you and other users to remember that it is an interface and not a class.

Members of an interface are public and abstract by default.

Note: Fields cannot be found in interfaces, but properties and methods can.

The interface needs to be “implemented”—akin to inherited—by another class in order for it to have access to its functions. Use the : symbol to implement an interface (exactly like with inheritance). The “implement” class provides the interface method’s body. It should be noted that when implementing an interface, the override keyword is not required:

Example

// Interface
  interface IAnimal 
  {
    void animalSound(); // interface method (does not have a body)
  }
 
  // Pig “implements” the IAnimal interface
  class Pig : IAnimal 
  {
    public void animalSound() 
    {
      // The body of animalSound() is provided here
      Console.WriteLine(“The pig says: wee wee”);
    }
  }
 
  class Program 
  {
    static void Main(string[] args) 
    {
      Pig myPig = new Pig();  // Create a Pig object
      myPig.animalSound();
    }
  }

Notes on Interfaces:

  •  Interfaces, like abstract classes, are not meant to be used to construct objects; for instance, the Program class does not allow the creation of “IAnimal” objects.
  •  Interface methods lack a body; instead, the “implement” class provides the body.
  •  When an interface is implemented, all of its methods need to be overridden.
  •  Fields and variables cannot be found in interfaces, but properties and methods can.
  •  Members of an interface are by default public and abstract.
  •  A constructor is not allowed in an interface since it cannot be used to create objects.

     

Why And When To Use Interfaces?

1)To increase security, only display an object’s crucial data and conceal other details (interface).


2) A class can only inherit from one base class; “multiple inheritance” is not supported in C#. Nevertheless, since the class can implement numerous interfaces, it is possible to accomplish it with interfaces. 

Note: Use commas to divide various interfaces that you want to implement (see example below).

Multiple Interfaces

Use commas to divide up various interfaces that you want to implement:

Example

interface IFirstInterface
  {
    void myMethod(); // interface method
  }
 
  interface ISecondInterface
  {
    void myOtherMethod(); // interface method
  }
 
  // Implement multiple interfaces
  class DemoClass : IFirstInterface, ISecondInterface
  {
    public void myMethod()
    {
      Console.WriteLine(“Some text..”);
    }
    public void myOtherMethod()
    {
      Console.WriteLine(“Some other text…”);
    }
  }
 
  class Program
  {
    static void Main(string[] args)
    {
      DemoClass myObj = new DemoClass();
      myObj.myMethod();
      myObj.myOtherMethod();
    }
  }

C# Enums

An enum is a unique “class” that stands for a collection of constants, or read-only/unchangeable variables.


Use the enum keyword (rather than class or interface) to build an enum, and use commas to divide the enum items:

Example

enum level
{
  low;
  medium;
  high;
}
you can access enum items with the dot syntax:
    Level myVar = Level.Medium;
      Console.WriteLine(myVar);
 
 “Specifically listed” is what “enumerations” (short for enumerations) mean.

Enum inside a Class

You can also have an enum inside a class:

Example

  class Program
  {
    enum Level
    {
      Low,
      Medium,
      High
    }
    static void Main(string[] args)
    {
      Level myVar = Level.Medium;
      Console.WriteLine(myVar);
    }
  }
The output will be:
Medium

Enum Values

By default, the first item of an enum has the value 0. The second has the value 1, and so on.

To get the integer value from an item, you must explicitly convert the item to an int:

Example

class Program
  {
    enum Months
    {
      January,    // 0
      February,   // 1
      March,      // 2
      April,      // 3
      May,        // 4
      June,       // 5
      July        // 6
    }
    static void Main(string[] args)
    {
      int myNum = (int) Months.April;
      Console.WriteLine(myNum);
    }
  }
The output will be :
3
Additionally, you can set your own enum values, in which case the numbers of the following elements will be updated:

Example

  class Program
  {
    enum Months
    {
      January,    // 0
      February,   // 1
      March=6,    // 6
      April,      // 7
      May,        // 8
      June,       // 9
      July        // 10
    }
    static void Main(string[] args)
    {
      int myNum = (int) Months.April;
      Console.WriteLine(myNum);
    }
  }
The output will be:
7

Enum in a Switch Statement

Switch statements frequently employ enums to search for corresponding values:

Example

  class Program
  {
    enum Level
    {
      Low,
      Medium,
      High
    }
    static void Main(string[] args)
    {
      Level myVar = Level.Medium;
      switch(myVar) 
      {
        case Level.Low:
          Console.WriteLine(“Low level”);
          break;
        case Level.Medium:
          Console.WriteLine(“Medium level”);
          break;
        case Level.High:
          Console.WriteLine(“High level”);
          break;
      }    
    }
  }
The output will be :
Medium  level

Why And When To Use Enums?

When you have values (month days, days, colors, deck of cards, etc.) that you know will not change, use enums.

C# Files

 

Working With Files

We can work with files thanks to the System.IO namespace’s File class:

Example

using System.IO;// include the System.IO namespace
File.SomeFileMethod();// use the file class with methods
The File class has many useful methods for creating and getting information about files. For example:
 
METHOD Description
AppendText() Appends text at the end of an existing file
Copy()Copies a file
Create()Creates or overwrites a file
Delete()Deletes a file
Exists()Tests whether the file exists
ReadAllText()Reads the contents of a file
Replace()Replaces the contents of a file with the contents of another fileWrite
AllText()Creates a new file and writes the contents to it. If the file already exists, it will be overwritten.

Write To a File and Read It

In the example that follows, we create a file called “filename.txt” and add some content to it using the WriteAllText() method. Next, we read the file’s contents using the ReadAllText() method:

Example

 using System.IO; // include the System.IO namespace
 
string writeText = “Hello World! “; // Create a text string 
File.WriteAllText(“filename.txt” , writeText); // Create a file and write the contents of writeText to it 
 
string readText = File.ReadAllText(“filename.txt”);  //Read the contents of the file
Console.WriteLine(readText); // Output the content   

C# Exceptions – Try..Catch

Several types of errors can arise when running C# code, including programmer-made errors, problems brought on by incorrect input, and other unforeseen circumstances.

Normally, C# will halt and provide an error message when an error occurs. This is known technically as C# throwing an exception (throw an error).

C# try and catch

You can specify a section of code to be tested for errors during execution using the try statement.

You can provide a block of code that will be run in the event that the try block has an error by using the catch statement.

The keywords “try” and “catch” appear in pairs:

Syntax

try
{
  // Block of code to try
}
catch (Exception  e)
{
  // Block of code to handle errors
}
Consider the following example, where we create an array of three integers:
This will generate an error, because myNumbers[10] does not exist.
int [ ]  myNumber = { 1, 2, 3 };
Console.WriteLine(myNumbers[10]); // error!
The error message will be something like this:
System.IndexOutOfRangeException: ‘Index was outside the bounds of the array.’

If something goes wrong, we can use try…catch to identify the problem and run some code to fix it.

The variable inside the catch block (e) and the built-in Message property are used in the example below to produce a message that explains the exception:

Example

try
      {
        int[] myNumbers = {1, 2, 3};
        Console.WriteLine(myNumbers[10]);
      }
      catch (Exception e)
      {
        Console.WriteLine(e.Message); 
      }
The output will be:
Index was outside the bounds of the array.


You can also output your own error message:

try

      {

        int[] myNumbers = {1, 2, 3};

        Console.WriteLine(myNumbers[10]);

      }

      catch (Exception e)

      {

        Console.WriteLine(“Something went wrong.”);

      }  

The output will be :

Something went wrong

Finally

Regardless of the outcome, the finally statement allows you to run code after try…catch:

      try

      {

        int[] myNumbers = {1, 2, 3};

        Console.WriteLine(myNumbers[10]);

      }

      catch (Exception e)

      {

        Console.WriteLine(“Something went wrong.”);

      }  

      finally

      {

        Console.WriteLine(“The ‘try catch’ is finished.”);

      }

The output will be:

Something went wrong.

The ‘try catch’ is finished.

The throw keyword

The throw statement allows you to create a custom error.

The throw statement is used together with an exception class. There are many exception classes available in C#: ArithmeticExceptionFileNotFoundExceptionIndexOutOfRangeExceptionTimeOutException, etc:

Example

static void checkAge(int age)
{
  if (age < 18)
   {
      throw new ArithmeticException(“Access denied – You must be at least 18 years old.”);
      }
    else
     {
      Console.WriteLine(“Access granted -You are old enough !”);
     }
   }
   static void main (string [ ] args)
  {  
    checkAge(15);
}
The error message displayed in the program will be:
System.ArithmeticException: ‘Access denied – You must be at least 18 years old.’

If age was 20, you would not get an exception:

Example

checkAge(20);

The output will be:
Access granted – You are old enough!