9.1. Class Syntax#

9.1.1. Overview#

To understand class and object-oriented programming (OOP), some important basic concepts learn first inlcude:

  • Class: A class is a blueprint, prototype, or template.

  • Class Members: In C#, a class contains members, which include fields, properties, methods, and events.

  • Class Instance: An object is an instance of a class. Namely, an object is created based on a class and therefore is an instance of that class. An object can be created using the new keyword.

There are related terminology that you will see about class and OOP:

  • Field: A field is a variable of any type that is declared directly in a class or struct. Fields are members of their containing type. A field stores a piece of data within an object. It acts like a variable and may have a different value for each instance of a type. [1]

  • Property: Properties expose fields. Fields should (almost always) be kept private to a class and accessed via get and set properties.

  • The this Keyword: In C#, the this keyword refers to the current instance of a class.

  • Reference Types: A type that is defined as a class is a reference type. Other types include: interface, struct, delegate, or enum.

  • Constructor: In C#, a constructor is called when an object is created to set default values. A constructor must have the same name as the enclosing class. Using constructor is not obligatory in C#. If no constructors are specified in a class, the compiler automatically creates a parameterless constructor.

9.1.2. Declaring Classes#

To declare a class, you need to use the class keyword and give a unique identifier (name) to the class. For example, you want to create a customer class to include some data and methods in one unit:

// [access modifier] - [class] - [identifier]

public class Customer
{
   // Fields, properties, methods and events go here...
}

Attributes to be considered when creating a class include:

  • Access Modifiers: The default access for a class type is internal. Basic levels of access for a class include [2] :

    • public: Access is not restricted. Anyone code can create instances of this class.

    • protected: Access is limited to the containing class or types derived from the containing class.

    • internal: Access is limited to the current assembly. [3]

    • private: Access is limited to the containing type.

  • Class Identifier: A unique name for the class. An identifier is the name you assign to a type (class, interface, struct, delegate, or enum), member, variable, or namespace. An identifier begins with a letter or underscore. As a convention, use PascalCase for class names and method names.

  • Class Body: The class body is surrounded by { }. The behavior and data are defined in the class body, including fields, properties, methods, and events on a class and are collectively referred to as class members.

  • Base Class or Super Class: Optional. Name of the class’s superclass; preceded by a colon (:).

  • Interfaces: Interface names implemented by the class; preceded by a colon (:).

9.1.3. Using a Class#

In the following example, there is a class called Program with a Main method. We define another class called DoMath and then, in the Main method of the Program class, 1) instantiate an object of the DoMath class by using the new keyword and 2) use the dot notation (.) to access a method defined in DoMath:

internal class Program
{
   static void Main(string[] args)
   {
      DoMath doMath = new DoMath();    // create an object using the new keyword
      int aSum = doMath.Sum(2, 2);     // use the [object].[method] syntax to use the methods
      Console.WriteLine(aSum);         // output 4
   }
}

class DoMath                           // class accessability level is default to internal
{
   public int Sum(int num1, int num2)
   {
      var total = num1 + num2;
      return total;
   }
}

In addition to store data as local variables and call methods in the same class, now we have alternatives for storing and accessing data in the methods within a new class that we write. Just like using the UI class or Random class, we now can better design, extend, and organize program functionalities.

When you use classes like StreamReader, you create a new StreamReader object using the new keyword and then use the ReadLine method (example in csharprepl):

> StreamReader reader = new StreamReader("ui.cs");
> string line = reader.ReadLine();
> line
"using System;"
>

As you can see, we are using the member access operator (.) to access a member of a namespace or a type. Calls to instance methods are always attached to a specific object. That has always been the part through the . of

object.method()

9.1.4. Constructors#

The constructor is a special method in the class:

  1. Its name is the same as the name of its type. For example, if we create a class named Contact, then the constructor method is also called Contact.

  2. Its method signature includes only an optional access modifier, the method name, and its parameter list

  3. Its method signature has no return type (and no static). Implicitly you are creating a default object from the class.

  4. The constructor can have parameters like a regular method. That means giving values to its fields. For example, you may want to store this state (the current condition of a system, such as the values of the variables) in instance variables name, phone and email if you are creating a Contact type:

      public Contact(string fullName, string phoneNumber, string emailAddress)
      {
         name = fullName;
         phone = phoneNumber;
         email = emailAddress;
      }

While the local variables in the formal parameters disappear after the constructor terminates, we want the data to live on as the state of the object. In order to remember state after the constructor terminates, we must make sure the information gets into the instance variables for the object. This is the basic operation of most constructors: Copy desired formal parameters in to initialize the state in the fields. That is all our simple code above does.

To further explain how constructors work, take a look at the following code:

internal class Program
{
   static void Main(string[] args)
   {
      CheckID check = new CheckID("taylor swift");
   }
}

class CheckID
{
   public string name;           // this is an instance field (variable)
   public CheckID(string name)
   {
      this.name = name;          // The "this" keyword refers to the current instance of the class
   }

   public void PrintResult()
   {
      // ... if ID for this name exists ...
      Console.WriteLine($"{name} has an existing ID!"); // using the "name" variable in method
   }                             // output "taylor swift has an existing ID!"
   // ....
   // ....
}

9.1.5. Static Classes & Methods#

In some conditions you may want to create static classes that provide static methods without instantiation. That means you do not need to use the new operator keyword to create a variable of the class type. Also, without the class instance variable, you access the members of a static class by using the class name itself. For example, if you have a static class called SomeMath:

static class SomeMath
{
   public static int Sum(int a, int b)    // a public static method
   {
      return a + b;
   }
}

To use the Sum method in the SomeMath class, you call it directly without creating a new object:

internal class Program
{
   static void Main(string[] args)
   {
      int aSum = SomeMath.Sum(2, 2);
      Console.WriteLine(aSum);      // output 4
   }
}

As another example, in the .NET Class Library, the static System.Math class contains methods that perform mathematical operations, without any requirement to store or retrieve data that is unique to a particular instance of the Math class. You can use the math methods directly in your code by referring to the static class name Math:

double dub = -3.14;
Console.WriteLine(Math.Abs(dub));               // 3.14
Console.WriteLine(Math.Floor(dub));             // -4
Console.WriteLine(Math.Round(Math.Abs(dub)));   // 3

Footnotes