Amazing classes and objects

Oleg Uryutin
4 min readFeb 26, 2021
Photo by Michael Dziedzic on Unsplash

Well-known facts about classes and objects in object-oriented programming are absolutely fascinating if you look at them with the eyes wide open.

Object-oriented programming (from now on OOP) is based on two key concepts: classes and objects. A class is a blueprint for creating objects, providing initial values for the state (member variables or properties), and implementing behavior (member functions or methods). A class can inherit from another class. In this case, it gets all the parent class’ properties and methods and extends them. These are well-known to everybody who writes object-oriented code. Let me introduce some new approaches or vision to OOP possibly you never thought about before.

The first remarkable fact is your OOP code is always strict typing because each declared object belongs to the appropriate class (type). Even when you don’t define a type of variable, you actually classify it as the class Any object. Any is assumed as a root class for global class hierarchy.

The second fact is everything is an object in your object-oriented programs, including literals (numbers, strings, and so on). The sentence

var name:String = “Oleg”

could be assumed as

var name:String = new String(“Oleg”)

where string object created implicitly at compilation time. So, every literal in your code could be considered as an object of some class; let’s call it a literal class:

10 is an object of the class Int,

3.14 is an object of the class Float,

“Oleg” is an object of the class String,

true is an object of the class Bool, etc.

The third statement follows from the previous two: object-oriented programs are ready to implement type inference or automatic type detection:

var name = “Oleg” // “name” is “String”
let pi = 3.14 // “pi” is “Float”
const yes = true // “yes” is “Bool”

The fourth surprising revelation is that objects are created by particular “new” statements but not by a class constructor. Yes, the function we used to call a constructor doesn’t create an object but just initialize them. Why? Let me explain.

  1. An object can refer to itself by the keyword this. The reference is available inside the constructor’s code, which means that an object named this was created before the constructor call. It’s true. It was created by the new statement.
  2. A constructor must return this object as a result of execution, but it’s missed in most programming languages.

So, the conclusion is a constructor is just an initialization method (no wonder it is named init() in Swift language). The sentence

var x:AClass = new AClass(someVal)

means

  • create new object “x” of the class “AClass”
  • call default initializer with a single parameter

As you can guess, the sentence

var x:aClass = new AClass

means creating a new object “x” of the class “AClass” without initialization.

Actually, a class can have multiple initializers for different sets of initial values:

class Value {
init() {…} // Default initializer: new Value()
init(x:Int) {…} // Overload of default initializer: new Value(100)
init huge() {…} // Named initializer: new Value.huge()
}

Separation of object creation and initialization makes redundant an object destructor. Indeed, garbage collectors used to kill objects in modern programming languages. Destructors are just “de-initializers” called eventually. The better and safe way is to use object’s methods attachable to system events instead:

class A {
// Initialize an object
init() {…}
// Called when event “clear” raised by system garbage collector
func onClear(event:Event) {…}
}

Now a couple of words about classes. Classes can be divided into four categories:

  1. Regular class. A blueprint for creating as many objects as we need.
  2. Singleton class. Looks like the regular class but can create only one instance of the object. The first new statement creates a unique object; each next just returns the previously created object again. Singleton’s initializer will be called only once, of course.
  3. Static class of library. It’s a class without objects. Any statement newcauses an error for such a class. In other words, a static class is an independent set of functions and global properties used as a library.
  4. Protocol. A set of properties and methods required to be or imported to a class. Protocols may not be used for object creation and initialization and look like common parts of different classes, singletons, and libraries.

Regular, singleton classes and protocols may use static properties and methods. Static classes contain static members only. Static members belong to the class, not an object. They can be referred by the name of the class:

class A {
static var x:Int = 10
static func incX():Int { return ++self.x }
}
var a:A = new A()
A.x = 100 // ok
A.incX() // 101
a.incX() // Error

To put it in a nutshell:

  1. We need only classes, singleton classes, libraries (static classes), and protocols to write robust object-oriented programs.
  2. We separate object creation with its initialization to make it work smoothly.
  3. Object destructor is an event function.
  4. You must use singleton classes when you need a single unique instance of the object to refer to it from any part of your program.
  5. Libraries are just sets of useful functions that require no initialization.
  6. When you need to use the same functionality for several classes, you make a protocol.

My next article will be dedicated to amazing things in class hierarchies and inheritance. See you soon!

--

--

Oleg Uryutin

System architect and master developer of the Aplextor