Chapter 7. Classes and OOP

Classes are a way of storing and organizing subclasses, functions, properties, and traits. OOP or Object Oriented Programming is a programming feature where copies of a class can be created. This chapter will go over static classes, properties, this, and OOP.

7.1 - Static Classes

A class is a way of holding (or templating) subclasses, functions, properties, and traits. The idea that the class is static (keeps itself sealed) means that it will not be instantiated (having a new instance of the class declared).

Let's say you wanted to have a class that would contain four functions to do +, -, *, and / with three parameters. The class will be called Calculator and will have those four functions inside of it.

func main () {
    println (Calculator.add (5, 7, 8));
    println (Calculator.mul (2, 5, 3));
}

class Calculator {
    func add (x, y, z) {
        return x + y + z;
    }
    func sub (x, y, z) {
        return x - y - z;
    }
    func mul (x, y, z) {
        return x * y * z;
    }
    func div (x, y, z) {
        return x / y / z;
    }
}

When the functions are declared inside of the Calculator class, they become children of that class. This means that you could not just call add from main, as add is a member (or child) of Calculator. To access add we use the . attribute access operator. The left hand side is the parent we are accessing, Calculator, while the right hand side is the attribute we wish to access, add.

7.1.1 Static - this

Hassium has a unique reserved variable called this. this refers to the parent object of wherever it is accessed from. Inside of the sub function in 7.1, this refers to Calculator. Inside of main, it refers to the global scope.

When calling other child functions of the same class, it is best practice to be explicit and use a this variable. Let's add to the Calculator class a function called special, which will return the result of adding x, y, and z divided by the result of subtracting x, y, and z.

class Calculator {
    func add (x, y, z) {
        return x + y + z;
    }
    func sub (x, y, z) {
        return x - y - z;
    }
    func mul (x, y, z) {
        return x * y * z;
    }
    func div (x, y, z) {
        return x / y / z;
    }
    func special (x, y, z) {
        return this.add (x, y, z) / this.sub (x, y, z);
    }
}

In the function Calulator.special, when the identifier this is encountered, the parent of special is accessed, which is Calculator.

7.1.2 Static - Properties

Properties are data members of a class which can be accessed and assigned to like a variable, although the programmer defines the specific behavior for the property.

Here is a class then has two properties, one that gets or sets the name, and one that gets the name in caps or sets.

func main () {
    Person.name = "Jerry";
    println (Person.name);       # prints "Jerry"
    println (Person.nameInCaps); # prints "JERRY"
    Person.name = "Susan";
    println (Person.nameInCaps); # prints ("SUSAN"
}

class Person {
    name { get { return this.name_ } set { this.name_ = value; } }
    nameInCaps { get { return this.name_.toUpper (); } set { this.name_ = value; } }
}

main begins by assigning the value "Jerry" to Person.name, which takes this value and assigns it to this.name_. The second line of main accesses or gets the value of Person.name, which in turn returns the value of this.name_. The third line of mine gets the value of Person.nameInCaps, which returns the value of this.name_.toUpper (). The fourth and fifth lines of main reassign Person.name and print out the caps value of the reassignment.

7.1.3 Static - Subclasses

Classes can also hold an infinite amount of classes inside them, referred to a subclasses. Here is a simple program that declares a class containing two subclasses and one function inside them.

func main () {
    ParentClass.SubClass1.SubClass2.subfunc ();
}

class ParentClass {
    class SubClass1 { 
        class SubClass2 {
            func subfunc () {
                println ("Hello, World! From ParentClass.SubClass1.SubClass2.subfunc");
            }
        }
    }
}

Output:

Hello, World! From ParentClass.SubClass1.SubClass2.subfunc

7.2 Object Oriented Programming

OOP (Object Oriented Programming) refers mainly to the instantiation (creation of a copy) of classes. Instead of having a static class where the state is fixed, programmers can treat the class like a template or blueprint, creating new instances of that class that have their own scopes.

Here is a simple program that shows what OOP can do.

func main () {
    Person person1 = new Person ("Bruce");
    Person person2 = new Person ("Michael");

    println (person1.name); # prints Bruce
    println (person2.name); # prints Michael

    person1.name = "Caitlyn";

    println (person1.name); # prints Caitlyn
    println (person2.name); # prints Michael
}

class Person {
    name { get { return this.name_; } set { this.name_ = value; } }

    func new (name : string) {
        this.name_ = name;
    }
}

Output:

Bruce
Michael
Caitlyn
Michael

There is a lot of new things to take in here. The Person class contains a function named new. This is the class constructor (function called when class is instantiated). This constructor takes in the string parameter name and assigns it to this.name_. The property Person.name then gets or sets this.name_. In main, the first two lines make new instances of the Person class by calling new Person. The names of each Person object are displayed on the fifth and sixth lines of main by accessing each Person's name property. The eighth line of main reassigns the person1 name property to "Caitlyn". The final lines of main then print out the new value of person1.name and the same value of person2.name.

7.2 OOP - Inheritance

Using inheritance (concept where classes can take on the members of other classes), a class can inherit the functions, properties, subclasses, and traits of another class.

Say we had a class called Person. That might contain basic information like name, age, and DOB. What if we wanted to have a class for President? This would still be a Person, also having a name, age, and DOB. But the President class might need to have other data, such as year elected and party.

Let's write and test the Person class.

func main () {
    println (new Person ("Michael", 43, "3/6/1973"));
}

class Person {
    name { get { return this.name_; } set { this.name_ = value; } }
    age { get { return this.age_; } set { this.age_ = value; } }
    DOB { get { return this.dob_; } set { ; } }

    func new (name : string, age : int, DOB : string) {
        this.name_ = name;
        this.age_ = age;
        this.dob_ = DOB;
    }

    func tostring () : string {
        return "Name: {0}, Age: {1}, DOB: {2}".format (this.name_, this.age_, this.dob_);
    }
}

Output:

Name: Michael, Age: 43, DOB: 3/6/1973

An important side note is the tostring function inside of the Person class. When println accepts an object argument, it calls tostring on the object automatically.

Now it is time to implement the President class. This class will need to have all the attributes of Person and more. To accomplish this, the President class will inherit the Person class using the : inherit operator.

func main () {
    println (new Person ("Dave", 43, "3/6/1973"));
    println (new President ("TheDonald", 70, "6/14/1946", "2016", "Republican"));
}

class President : Person {
    yearelected { get { return this.yearelected_; } set { ; } }
    party { get { return this.party_; } set { ; } }

    func new (name : string, age : int, DOB : string, yearelected : int, party : string) {
        this.name_ = name;
        this.age_ = age;
        this.dob_ = DOB;
        this.yearelected_ = yearelected;
        this.party_ = party;
    }

    func tostring () : string {
        return "Name: {0}, Age: {1}, DOB: {2}, Year Elected: {3}, Party: {4}".format (this.name_, this.age_, this.dob_, this.yearelected_, this.party_);
    }
}

Output:

Name: Dave, Age: 43, DOB: 3/6/1973
Name: TheDonald, Age: 70, DOB: 6/14/1946, Year Elected: 2016, Party: Republican

The class President inherits all of the members of Person and adds the properties yearelected and party. Because both the Person class and the President class both have the member function tostring, one version of tostring must be chosen. Since it is Person that is being inherited, the version of tostring in President will be the one used.

Chapter 7 - Exercises

Exercise 7.1

Create a class called Dog which has all the attributes of a dog. Include some methods like bark and eat.

Exercise 7.2

Create a class called BigDog which inherits the attributes from Dog but adds methods relevant to a larger dog.

results matching ""

    No results matching ""