Practical 4: Abstraction

CAB201 - Programming Principles

School of Computer Science, Faculty of Science

Abstraction in C#

Abstraction is used to hide the complexity of a certain task by showing only the necessary details. In C#, this is achieved using methods and interfaces.

// Method
public static bool TryParse (string s, out bool result) 
{
    switch (s.ToLower()) {
        case "true" or "t":
            result = true;
            return true;
        case "false" or "f":
            result = false;
            return true;
        default:
            result = false;
            return false;
    }
}
// Interface
public interface IShape {
    double Area();
    double Perimeter();
}
class Circle : IShape { // Implementing interface
    public double Area() {
        return Math.PI * Math.Pow(radius, 2);
    }
    public double Perimeter() {
        return 2 * Math.PI * radius;
    }
    private double radius;
    // ... other members
}
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

Methods

A method contains a series of statements. The abstraction is achieved by the method's signature (name, parameters, and return type).

public static bool TryParse(string s, out bool result) {
    // This can be anything, as long as it:
    // - Sets result to a boolean value
    // - Returns a boolean value
}

The signature is like a contract: it tells the caller

  • What the method does (now how), including the name, and return type.
  • What the method needs to do its job, being the parameters.
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

Passing by Value

In C#, primitive types (int, bool, double, etc.) are passed by value, meaning that the method receives a copy of the value. Changes to the parameter do not affect the original value.

public static void Increment(int x) {
    x = x + 1;
    Console.WriteLine($"Inside method: x = {x}"); // 6
}
public static void Main(string[] args) {
    int x = 5;
    Console.WriteLine($"Outside method before Increment: x = {x}"); // 5
    Increment(x);
    Console.WriteLine($"Outside method after Increment: x = {x}"); // 5
}
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

Passing by Reference

Objects or arrays are passed by reference, meaning that the method receives a reference to the original object. Changes to the parameter affect the original object.

public static void Increment(int[] arr) {
    arr[0] = arr[0] + 1;
    Console.WriteLine($"Inside method: arr[0] = {arr[0]}"); // 6
}
public static void Main(string[] args) {
    int[] arr = new int[] {5};
    Console.WriteLine($"Outside method before Increment: arr[0] = {arr[0]}"); // 5
    Increment(arr);
    Console.WriteLine($"Outside method after Increment: arr[0] = {arr[0]}"); // 6
}
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

The ref keyword

ref and out can be added to the parameter list to force the method to pass the parameter by reference.

public static void Increment(ref int x) {
    x = x + 1;
    Console.WriteLine($"Inside method: x = {x}"); // 6
}
public static void Main(string[] args) {
    int x = 5;
    Console.WriteLine($"Outside method before Increment: x = {x}"); // 5
    Increment(ref x);
    Console.WriteLine($"Outside method after Increment: x = {x}"); // 6
}
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

The out keyword

out is similar to ref, but it is used to output a value from the method, meaning:

  • The parameter cannot be read before it is assigned.
  • The parameter must be assigned before the method returns.
public static void Increment(int current, out int next) {
    // next = next + 1; // Error: next is not assigned
    next = current + 1; // Without this line, it would be an error
}

Using out is similar to ref:

int x = 5; Increment(x, out x);
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

Interfaces

An interface is a contract that defines a set of methods and properties.

A class that implements an interface must provide an implementation for all the members of the interface.

public interface IShape {
    double Area();
    double Perimeter();
}
class Circle : IShape {
    // Leaving this empty would cause an error 
}
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

Implementing an Interface

To implement an interface, define a class and use the : operator to specify the interface to implement.

class Circle : IShape {
    public double Area() {
        return Math.PI * Math.Pow(radius, 2);
    }
    public double Perimeter() {
        return 2 * Math.PI * radius;
    }
    private double radius;
    // ... other members
}
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

Static Methods

Static methods are associated with the class, not with any instance of the class. They are called using the class name.

class Calculator {
    public static int Add(int a, int b) {
        return a + b;
    }
}
class Program {
    public static void Main(string[] args) {
        int result = Calculator.Add(5, 3);
    }
}
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

Instance (non-static) Methods

Instance methods are associated with an instance of the class. They are called using the instance name.

In Number.cs:

class Number {
    private int value;
    public Number(int value) {
        this.value = value;
    }
    public void Add(int x) {
        value += x;
    }
    public int GetValue() {
        return value;
    }
}

In Program.cs:

class Program {
    public static void Main(string[] args) {
        Number firstNumber = new Number(5);
        firstNumber.Add(3);
        int result = firstNumber.GetValue(); // 8
        // Calling the method on a different instance
        // gives a different result
        Number secondNumber = new Number(10);
        secondNumber.Add(3);
        result = secondNumber.GetValue(); // 13
    }
}
CAB201 - Programming Principles
School of Computer Science, Faculty of Science