Classes, Objects and Instances

Topics for this page:

Background

Python, Kotlin or Java, which best supports Object Oriented Programming (OOP)?

History.

Simula 67 (in 1967) was probably the first Object Oriented Language.  It was a great language, but wow was it slow!  And slow even on the massive mainframe computers it lived on.

The origin of C++ was to add the power of Object Oriented Programming to the very efficient language C, while still delivering real performance. In first reference book on C++ was released in 1985 (tired of waiting for everyone to have access to the internet?) at a time when micro-computers were popular, but far slower than even old mainframe computers.  The result was a language with great control over how objects were created, but in reality necessarily severely compromised by the features to deliver performance.

Java began life as Oak in 1991, but was only used by the original team until 1995 and then had a very short gestation to reaching 1.0 in 1996.  Java delivered greater ease of Object Oriented Programming than C++, and with good performance even with the added layer of a virtual machine.  While the language is hardly truly Object Oriented throughout,  it struck winning formulae with a balance of Object Oriented and performance.

Python had origins also in 1991, but did not really get public exposure until python 2.0 in the year 2000, and did not get full object orientation until ‘new style classes’ were introduced at the end of 2001. Computing power had moved a long way between 1996 and 2001 (consider the 150Mhz 1995 Pentium pro vs the 1.3Ghz 2000 Pentium 4),  and python was targeting easy of programming over ultimate performance anyway.  As you can guess as a result python was able to be Object Oriented throughout instead of just having an outer veneer of being Object Oriented.  But yes, still slower than Java.

Of course for Kotlin, designed in 2011 and having version 1.0 released in 2016, having Object Oriented structure throughout and adding features for functional programming as well was not even really a challenge. But slower than Java? Sometimes, but a 2016 technology compiler that ran run in a 2016 computer with gigabytes of memory available (windows 3.1, the common version at the time of Java release, required 1MB of Ram!) can optimise and produce almost the same code.  Oh yes, the compiler is slower than a Java compiler can be, but is it a problem?

OOP Myths.

But Java has created some OOP myths with almost a generation of programmers learning OOP on Java.

“This program cannot be True OOP, where are the getters and setters!”

That encapsulation requires getters and setters is actually true.  That you have to write your own getters and setters just to access and store data is not true.  Both python and kotlin automatically provide getters and setters without the programmer noticing unless the program requires non-standard behaviour from the getters and setters. Java requires the program writes their own getters and setters in order to allow breaking the rules of OO for performance reasons.

True OOP requires and functions and data to be inside a class so every thing is an object!

True OOP does have everything as an object.  Functions, all data types, everything.  For performance reasons Java broke this rule.  Understandable, but breaking the rules of OOP does not make the language more OO.  Functions should be ‘first class functions’ and in java they were not, for performance reasons.  Putting the non-OOP functions inside an object at least gave them an Object Wrapper, and the same applies for Java primitive data types.  Modern OO languages do not need to wrap functions or data in a class because functions and data are always already objects.

defining classes: constructors and init

python vs kotlin Syntax

# syntax is:
class <Name>(<base classes>):
    def __init__(self, <parameter list>):
        # put init code here
#now example 1
class Fred:
    def __init__(self, var1, var2):
       self.var1 = var1
       self.var2 = var3
       self.container = []
#and example 2
class Fred(BaseClass):
    def __init__(self, var1, var2):
       super().__init__(var1)
       self.var1 = var1
       self.var2 = var3
       self.container = []
           # rest of init here

Hopefully the above python code is self explanatory. Example 2 adds a base class.  I do not deal with multiple inheritance at this time, and will devote a specific page at some future time as for python it gets complex, and for kotlin it requires additional concepts.  Now here is the kotlin ‘imitate python’ equivalent to example 1.

//syntax is:
//
<optional modifier> class <name>(<default constructor params>): <base>
//
// example 1a:bad version- to be python like - not best kotlin
class Fred{
    val var1: Int
    val var2: String
    val container: MutableList<Int>

    constructor(var1: Int, var2:String){
        this.var1 = var1
        this.var2 = var2
        this.container = mutableListOf<Int>()
    }
}
// example 1b: still bad version- to be python like again- not best kotlin
//  move 'constructor' to class definition, now contructor body is 'init'
class Fred constructor(var1: Int, var2:String){
    val var1: Int
    val var2: String
    val container: MutableList<Int>

    init{
        this.var1 = var1
        this.var2 = var2
        this.container = mutableListOf<Int>()
    }
}

// example 1c:better - 'constructor' keyword omitted and defines variables
// in the primary constructor
class Fred(val var1: Int, val var2: String){
    val container: MutableList<Int>

    init{
        container = mutableListOf<Int>()
    }
}

First the ‘not the best kotlin way’ examples. Is constructor or init the best equivalent python __init__? The first example keeps the class definition more similar to python, and uses a constructor to perform the role of the python __init__. In kotlin, a class can have multiple different constructors to enable constructing an object from different types. So there could be another constructor accepting String in place of Int for the parameters.

But where the python code simply assigns to self.var1 without first declaring var1, in kotlin all variables must be declared, so example aside from the declarations of the three instance variables (var1, var2 and container) and constructor in place of __init__, 1a above looks almost directly like the python version. However, in this form, there is more code than the python version.

Version 1b above moves the constructor(var1: Int, var2:String to the class declaration. Doing this makes this the default constructor for the class, but the body of the constructor method cannot be on this line declaring the class so the body of the constructor is now called init, and the class declaration reads: class Fred constructor(var1: Int, var2:String).
init is the special reserved word to identify the block of code which is the body of the default constructor.

So example 1b is very similar to example 1a, but introduces the concept of a default constructor and the init block.

Example 1c introduces some improvement. A common pattern is that values to the constructor (__init__) as saved as instance variables. Simply adding var or val in the constructor means the parameter is the declaration, plus this result in the constructor automatically saving the values passed in. So we lose 4 lines of code as unnecessary (two declarations, plus 2 assignments). We can also omit the word ‘constructor’ for the primary constructor except for some rare special cases. So now the code is almost as brief as the python code. But there are still optimisations to come.

// example 1d:best
class Fred(val var1: Int, val var2: String){
    val container = mutableListOf<Int>()
}
// example 2
class Fred(val var1: Int, val var2: String):BaseClass(Var1){
    val container = mutableListOf<Int>()
}

So for example 1d, the code is now more concise than python, despite the declaration of variables. Yes, container does now look like a python class variable, but this is how instance variables are in kotlin. So the code is brief with types, and perhaps more so than the code without types. This is because the remaining code in the kotlin constructor prior to this step, initialisation of container, can happen at the declaration of container. So no Normally, all code needed in a constructor is setting initial values, so normally no init block is needed as initial values at the definition, either automatically in the case of default constructor parameters, or at the definition in the main block of other instance variables.

Example 2 covers a class with a base class, just for completeness, to have the syntax covered.

instance vs class variables

Consider the following python code:

class Person:
    age = 21

    def __init__(self, name):
       self.name = name
       self.otherName = ""
       self.fullName = name

name, otherName and fullname are instances variable or properties, which means for each Person there is a new copy of each variable. Without a person object, there is no name, otherName or fullName. But age is a class variable, so it exists exactly once, even if there are no Person instances, and regardless of how many person instances.

>>> p1= Person("Fred")
>>> p2= Person("Tom")
>>> p1.age  # access class variable just like instance variable
21
>> p2.age  # same value both times
21
>>> Person.age = 22 # change value in class
>>> p1.age # and p1.age automatically has the new value
22
>>> p2.age # and so does p2.age
22
>>> p2.age = 19 # set p2.age creates an instance variable
>>> p1.age # p1 is still using the class so unchanged
22
>>> p2.age # but p2.age shows the instance, which hides the class variable
19
>>> del p2.age // now delete the instance variable
>>> p2.age  // but the class is still there
22
>>> 

The above code plays with how instance variables in python can have the same name as class variables, but hide the class variable.

Now to kotlin. As we saw in class definition, instance variables in kotlin are defined in the way closer to how class variables are defined in python.

Code which appears in the class definition and defines and sets the value of a variable, is actually run every time an object of the class is instanced. This is very useful, because it makes the most common case the one that is simpler, while with python the simpler code is the class variable, and they are less common.

With kotlin there is no automatic class object at run time, with information on class methods and properties held internal to the compiler. To have an object at run time to hold information for the class information for runtime including class variables, kotlin classes have a ‘companion object’. So the reverse of python, kotlin instance variables are declaring at the class level, and class variables are declared inside a container, the companion object container.

The kotlin companion object is the parallel of the class object in python. Any methods or variables in the companion object will be class based and exist once per class, regardless of whether there are zero or more instances of that class.

Most access to class based data will happen from inside the class, but if you do wish to access class based data from outside the class, you do need a ‘getter’ and/or a setter, which are not normally needed in kotlin, but this is an unusual case, and for completeness it is covered here.

class Person(val name:String) {  // instance variable declared in constructor

    var otherName = "" // an instance variable not from a parameter
    var fullName = name //instance variable manually set from parameter

    companion object {
       var age = 21  // class variable age
    }

    var staticAge get()= age   // instance property as getter and
        set(value){age = value}   // setter for age - see properties
}

The staticAge is needed for the example, but most often access to get or set a class variable like age will happen from within the class, so no staticAge would be needed.

p1 = Person("Fred")
p2 = Person("Tom")
p1.staticAge  // access class variable like instance only within class
21
p2.staticAge  // use instance with getter from outside class
21
Person.age = 22 // change value in class
p1.staticAge // and p1.age automatically has the new value
22
p2.staticAge // and so does p2.age
22
// cannot create instance value at runtime
// no workable equivalent to python class and instance with same name

The main point is that while defining a variable in the class scope in python creates a class variable, in kotlin creating at this scope creates normal instance variables (or properties).  Class variables (also know as static class variables) in kotlin are created within the companion object for the class, which is a single object as a container for the class, rather than each instance of the class.

self vs this

Access to variables of an object from outside the code of class definition (as in the previous example), is the same for python and kotlin. The code p1.name will access the name variable from the object p1.   Code inside the class must work without any actual object name, so another naming system is needed.  The naming for python is self to indicate the current object, and for kotlin this to indicate the current object.  But the python self is needed far more often than the kotlin this, so in python self.name for the object variable or property, and this.name in kotlin, but in kotlin the this. is only needed when there is a parameter or local with the same name, and normally the this. can be omitted.   So a lot less this in kotlin than self in python.

Again, in python the first parameter to each method in a class should be self, this is not included in the parameter list in kotlin.  Again, less this than self.

# consider in method defintion
    def setNames(self, name): # self as first parameter
       self.name = name
       self.otherName = ""
       self.fullName = name # use name as fullname
//method definition in kotlin
   fun setNames(name): // no 'this' in parameter list
       this.name = name // 'this.name' is property, 'name' is parameter
       otherName = "" // only one 'otherName', so do not need 'this.'
       fullName = "" // also only one 'fullName'

properties: getters and setters

Traditionally, java programmers have been taught that encapsulation (a key part of OO) requires building a class so that how things work can be changed without affecting code using the class. To do this ‘getters’ and ‘setters’ are required, to provide for changes to how data inside the class is used. Instead of allowing a variable to be accessed or set from outside the class, a getter method is created to get the value, and a setter method to set the value. The idea is functions already there in place ready for a possible time when getting or setting is to be become more complex.
Modern languages have identified problems with this approach:
almost all getters and setters just get or set the value and do nothing else so they just bloat the program
it is much clearer for the calling code to get the value of a variable or have an assignment statement to set the value – even when what is happening inside the class is more complex

The solution is:
require code only for the complex cases
ensure setting and getting from outside the class looks the same for simple and complex and is most readable.

Consider this python class:

class Person:
    def __init__(self, name):
       self.name = name
       self.otherName = ""
       self.fullName = name

>>> tom = Person("Tom")  #instance object
>>> tom.fullName = "Tom Jones" # set property using object
>>> tom.fullName  # get property
'Tom Jones'

getting and setting is as simple as possible when using the class, but what if we do wish to ‘complicate’ the fullName property changing the value from being simply its own data, to being the result of name together with otherNames?
Consider:

class Person:

    def __init__(self, name):
       self.name = name
       self.otherName = ""

    @property
    def fullName(self):
	    return " ".join([self.name,self.otherName])
    @fullName.setter
    def fullName(self,value):
	    if " " in value:
	        self.name,self.otherName = value.split(" ",1)
	    else:
	        self.name = value
	        self.otherName = ""
>>> bob = Person("Bob")
>>> bob.otherName = "Jones"
>>> bob.fullName
'Bob Jones'
>>> bob.fullName = "Bobby Smith"
>>> bob.name
'Bobby'
>>> bob.fullName
'Bobby Smith'
>>> bob.otherName
'Smith'

Now we have the new implementation, and all code written before the change will still work.

class Person(var name:String) {  // instance variable declared in constructor

    var otherName = "" // an instance variable not from a parameter
    var fullName
        get()= listOf(name,otherName).joinToString(" ")
        set(value) {
            val (first,second) =
                    if(' ' in value) value.split(" " ,limit=2)
                    else listOf(value,"")
            name = first
            otherName = second
        }
}

The kotlin code for having getters and setters is less changed by adding getters and setters. Simply follow the variable (or value) property declaration with the get and/or set methods.

More?

What is not covered?
Super, which I feel needs no explanation, and
Delegated properties and more complex cases with does need more. I will add a separate page on these but for now see this page, and delegated properties are described here.

Extension functions will also be covered separately.

Advertisements

OOP vs Functional: No contest!

Moving to kotlin, the question can arise: “should I program in OOP (Object Oriented Programming) style, or move to Functional programming?”.  This page examines reviews what Object Oriented programming really means, what functional programing is, and outlines how there is no incompatibility if the correct approach to OOP is in place, and the two paradigms are best when combined.

Functional Programming vs Programming with functions.

What is FP?

Almost all modern programs use functions, but just using functions is not Functional programming.  What is required is functions that are ‘functional’ in the mathematical sense, not programming in the ‘using functions’ sense.  A mathematical function, or ‘pure function’ operates on the supplied arguments and returns a result and does nothing else. No ‘side effects’. Nothing changed by the function, no internal variables altered that will result a future call of the same function dealing with different values.

The best test for a ‘pure function’ is: will the result, and all aspects of calling the function be identical every time the function is invoked?

Limitations of ‘pure’ Functional Programing.

Any ‘side effect’ of calling the function disqualifies the function from being a ‘pure function’, as the only output from the function is the result of the function.  The reality is a program without any ‘side effects’ is actually useless, as input/output is generally a side effect.  The answer can to a problem may be able to be calculated using ‘pure functions’, but actually showing the answer is going to require input/output.  So while a program may incorporate ‘pure functions’, no program will be entirely functional program.   The second important point is that ‘pure functions’ can be built in any language.

Language requirements.

Languages that supports functional programming give tools to make it easy to see what code will qualify as a ‘pure function’, and what does not.

OOP vs non OOP programming.

What is OOP?

OOP means different things to different people.  To some the ‘class’ statement is the essence of object oriented programing, yet while ‘javacript’ has no class statement, but supports object oriented programming.

A more useful view of object oriented to think of ‘classes’ simply as ‘types’.  A type permits operations on that type. These operations are ‘methods’ of that type, that is computing that can be done with that type.  When different types (e.g. ‘int’ and ‘string’) each have their own interpretation of the same operation (e.g ‘+’ or plus) then we have one of the anchors of being object oriented: polymorphism.  As almost every language has several different types which each have their own version of ‘+’, if follows that every language has some elements of object oriented. The core concepts of object oriented is present in almost every program, but object oriented programing is more than just some exposure to the concepts.  An object oriented program does not just use the type system and which will already have some degree of object oriented approach, rather, and object oriented program extends the type system creating its own ‘types’ or ‘classes’.  Further, a an object oriented program, is about using this approach as the basis of the solution.

The limitations of pure Object Oriented

Pure object oriented is usually stated to have four ingredients:

  • polymorphism: the ability of different classes to effectively all act the same in some way but implementation their own version of one or more functions or operations to operate in an equivalent way
  • encapsulation: the implementation of the class (or type) is coded within the class and  code using the class has no need to consider how the class is implemented and will not be impacted if the implementation changes
  • inheritance: classes or types can inherit or ‘sublcass’ from a ‘superclass’.  This enables both reuse of code, and is a key tool for building polymorphism when more than one class subclasses from the same parent has its own implementation of the methods of the superclass
  • abstraction: this is giving the class an interface designed around the logical use of the class, and not simply a reflection of the mechanics of the underlying code

Of these four usually quoted points, all but one are mostly about techniques to do OOP well, while encapsulation is really a test of OOP or not OOP. ‘Pure’ OOP code be built from purely from Objects with the code encapsulated within the classes.

The language Java provides a perfect illustration of why ‘pure’ OOP is a mistake. Where efficiency dictates, the despatch tables within classes required for encapsulation are a performance killer.  For performance.  low level, close to the computer objects are best being reduced by the compiler to direct inline code.  This does not stop such low level object classes adhering to the object model, or at least linguistically, being objects.  However Java even goes as far a simply dropping all pretence of objects, or Object Oriented code for ‘native types’.  In contrast to Java itself, the Java must write all code in classes.  The simple example of the ‘hello world’ which results in a pointless class wrapper containing the ‘main’ method, illustrates how even enforcing there are classes, does not create an Object based approach, and that for some code, there is no object based approach.

Language Requirements.

In python, a programmer could implement their own class system using dictionaries of methods and properties. But creating new objects requires allocating memory, keeping track of when an object is no longer needed and freeing that memory. In fact some ‘object oriented’ languages (like c++) require programs to manually control garbage collection (returning memory to ‘free memory’ when objects are no longer needed).  Every feature needed for OOP can be implemented with no special features at all, however is most languages ‘DIY’ would be laborious and distract from the application. No special feature is needed to do OO, but to do OO well, a good syntax and feature set is essential.

Functional vs OOP: No contest!

The optimal FP approach, is avoid side effects wherever possible.  The optimal OOP approach is for all data in the program to be an object.  FP sounds like focusing on the purity of the logic steps, OOP is about focusing on the data.  But FP programs still need data, and operations on data, and regarding that data as objects and empowering the data makes sense. There is no problem combining both paradigms in a single program.

Some argue that the OO philosophy encourages programming in a ‘state-driven’ manner that is the antithesis of FP, but this argument ignores the foundations of the best FP languages have OO based type-systems.

OO itself makes it easy to break FP principles, but also can make it easy to follow FP principles.  Kotlin does give more tools to support using OO together with FP style than python does, but this can be done with either language.  As a simplistic example, a ‘val’ in kotlin is a variable which can never be reassigned, with python a programmer can still have variable which is never reassigned, but the programmer will need document this and check themselves that the rule is followed.

Misguided OOP vs the OOP and FP combination.

Recently, I was speaking with a programmer who declared, “Object Oriented is dead, Functional Programming is the correct way!” He had a link to a video describing how OOP programs could break all the principles of FP.  OOP programs that behave this way are simply bad OOP programs! I have not found that video again, but I can recommend this (rather long) video by ‘uncle’ Bob Martin on functional programming (see 50:00 minutes in for the points on OOP with functional programming).  Misguided OOP tries to force everything, including functions, into objects.  A classic example of this is with Java where even the main function of a program has to be wrapped within an object that adds nothing.  Kotlin moves from the misguided OOP of Java in many ways, for example by making functions first class objects.  As this guide progresses, the theme of Kotlin adapting true, more mature OOP into the system, and in a Functional Programming compatible way, while still maintaining java compatibility, is repeated over and over.