Learn Programming

Learn D Programming Lesson 9 - Classes

What is a class?

A class is a blueprint from which objects are created. An object is a data structure mainly made up of variables and functions. Classes are used to represent real world or abstract objects like a customer or a bank account. Classes make programming much easier because they group related variables and functions together. They also make programming easier because they are representations of real world objects instead of just a whole lot of lines of code.

Creating a class

Classes are usually each created in a separate file and this also means in a separate file to the main program. The following is an example of a class called BankAccount. It must be created in a file called BankAccount.d. Here is the code for the BankAccount class followed by an explanation.

import std.stdio;

class BankAccount
{
   int balance;

   void Deposit(int amount)
   {
      balance = balance + amount;
   }

   void Withdraw(int amount)
   {
      if (amount < balance)
         balance = balance - amount;
      else
         writefln("Not enough money in account");
   }
}

The first line is an import statement like we have used in most of our other programs. You need to still import the modules you want to use even if they have been imported somewhere else. The class keyword is used to define a class and is followed by the name of the class which in this case is BankAccount. A class uses curly brackets to contain its code just like a function. The next thing is a declaration of a variable called balance which is used to hold the bank account's balance. The class contains 2 functions called Deposit and Withraw for putting money into the bank account and taking money out. The Withdraw function makes sure that there is enough money in the bank account before withdrawing the money.

Using a class

A class is useless unless it is used in a program so we are going to create a program in a file called test.d that will use the BankAccount class. To be able to use a class in an external file you need to import it just like you have to import std.stdio. You can create an object from a class by declaring a class variable and then setting it to a new instance of the class using the new keyword. Here is the code for the main program in which an object called MyAccount of the class BankAccount is created.

import std.stdio;
import BankAccount;

void main()
{
   BankAccount MyAccount = new BankAccount();
}

To use a variable or a function in a class all you have to do is put a dot after the object name and then the name of the variable or function. Here is an example that uses the Deposit and Withdraw methods of the MyAccount object and prints the balance as it goes along.

import std.stdio;
import BankAccount;

void main()
{
   BankAccount MyAccount = new BankAccount();
   writefln(MyAccount.balance);
   MyAccount.Deposit(1000);
   writefln(MyAccount.balance);
   MyAccount.Withdraw(500);
   writefln(MyAccount.balance);
}

Compiling multiple classes

If you are compiling your programs from the command line then you need to add the name of the class source file to the usual compilation command. Here is the command you should be using.

dmd test.d BankAccount.d

Access modifiers

An access modifier is a keyword that determines the type of access that external objects have to a class. One example is the private keyword which you can use to hide variables and functions from anything outside of the current class. The public keyword does the opposite and makes things accessible from any other place in the program though public is the default so it can be left out.

Hiding variables and functions in a class seems to make no sense until you see how they are used. In the BankAccount class from above there is a function called Withdraw which takes money out of the bank account. The function also checks if the amount to withdraw is lower than the balance but someone could easily avoid the check by just setting the value of the balance variable. You can prevent that kind of thing by making balance private. You have to then create another method for getting the balance of the account. Here is the code for that.

import std.stdio;

class BankAccount
{
   private int balance;

   int GetBalance()
   {
      return balance;
   }


   void Deposit(int amount)
   {
      balance = balance + amount;
   }

   void Withdraw(int amount)
   {
      if (amount < balance)
         balance = balance - amount;
      else
         writefln("Not enough money in account");
   }
}

import std.stdio;
import BankAccount;

void main()
{
   BankAccount MyAccount = new BankAccount();
   writefln(MyAccount.GetBalance());
   MyAccount.Deposit(1000);
   writefln(MyAccount.GetBalance());
   MyAccount.Withdraw(500);
   writefln(MyAccount.GetBalance());
}

Constructors

A constructor is a method that is run when an object of a class is created. You may have noticed that when you declare an object of a class using the new keyword it also has the name of the class followed by brackets and this is because it is running the constructor. You create a constructor for a class by creating a method called this. A constructor is used to initialize the values of an object. Here is an example of the BankAccount class with a constructor that sets the balance to 100.

import std.stdio;

class BankAccount
{
   private int balance;

   this()
   {
      balance = 100;
   }


   int GetBalance()
   {
      return balance;
   }

   void Deposit(int amount)
   {
      balance = balance + amount;
   }

   void Withdraw(int amount)
   {
      if (amount < balance)
         balance = balance - amount;
      else
         writefln("Not enough money in account");
   }
}

import std.stdio;
import BankAccount;

void main()
{
   BankAccount MyAccount = new BankAccount();
   writefln(MyAccount.GetBalance());
}

Constructors can take parameters just like other functions. You must give values for the parameters of the constructor when declaring an object of a class. Here is an example of the BankAccount class that has a constructor that takes the balance as a parameter.

import std.stdio;

class BankAccount
{
   private int balance;

   this(int bal)
   {
      balance = bal;
   }


   int GetBalance()
   {
      return balance;
   }

   void Deposit(int amount)
   {
      balance = balance + amount;
   }

   void Withdraw(int amount)
   {
      if (amount < balance)
         balance = balance - amount;
      else
         writefln("Not enough money in account");
   }
}

import std.stdio;
import BankAccount;

void main()
{
   BankAccount MyAccount = new BankAccount(500);
   writefln(MyAccount.GetBalance());
}

Practice

Try creating a class called Person with variables for the first name and the last name of a person and a function called GetFullName which returns the first name and last name joined together. Use a constructor to initialize both the first name and the last name to "Not set". After that make a program that uses the Person class.