Topics for this section:
- Class Level Objects & Companion Objects: Key Terminology.
- the simplest case – one object type
- Python – an additional object type requires precise terminology
- Kotlin: the companion object equates to the Python class object
- Class & Companion Variables and Methods vs instance methods and variables
- Terminology for Clarity: Class Level Object, Variables and Methods
- instance vs class variables in python
- an alternative explanation of instance vs class for python
Class Level Objects & Companion Objects: Settling on Terminology
This bliki assumes a reader has knowledge of what class is, and what is an object is, but precise usage of the terminology does change from language to language, so please tolerate a review of very basic concepts in order to be specific about exact terminology
Consider a Person class, that will have two instances, one for “Jack” and one for “Jill”.
The simplest case: the base of confusion
With a compiler language, the compiler will read the class definition and generate the code for all methods required by the class. The compiler will also store in an internal data structure of the compiler all relevant information about Person class. For any code relating to the class, the compiler will use the information it has stored about the class to enable generation of the appropriate code.
At run time the Jack and Jill instances Jack and Jill of the person class are created. So there are two object, both instances of same class: the Person class. In this environment, any reference to a Person object must be a reference to the Jack or Jill instances.
Python: An additional object type requires precise terminology.
Now consider Python. The python language also builds the internal data structure containing the relevant information about the person class, and in fact that data structure is an object of the ‘type’ class. But with python, there is not the same distinction between compile time and run time. The running program can also access the ‘internal data structure’ – which in fact makes it no so internal. At run time, there will be an instance of the type class : Person, and once Jack and Jill are instanced, there will be two instances of the Person class: Jack and Jill. As there is only one Person class regardless of how many instances of Person are generated, there will always be one Person class level object, regardless of whether there are zero or one hundred instances. So with the Jack and Jill example with python, there are now three objects available to the running program. A type object: Person, and two Person Objects: Jack and Jill. When we say ‘Person object’, do we mean the object describing the class, or one of the two objects which are instances of the class?
In python, the convention is that the object describing the class is the class, and a class variable is a variable within that object describing the class, as opposed to a variable within an instance of the class such as Jack and Jill. The variables within these instances are instance variables. This contrasts with the previous simple case, where, with only one instances type of object for any class, the term
class variable can only mean an instance variable.
Kotlin: The companion Object equates to the Python class object
Kotlin also provides for an object holding data at the class level, the companion object. Unlike Python, not all classes have a companion object. Classes with a companion object at class level, must specifically declare a companion object. Keeping the companion object as optional allows the metaprogramming power of Python, or the closer to C++ internal simplicity of Java.
Like the Python class object, there is one companion object for a class, regardless of how many (or even any) instances of the class are created.
Class & Companion Variables and Methods vs instance methods and variables
With Kotlin, the developer can declare variables within the companion object, and with Python class variables can be declared at class level. In both cases, the provides a single variable shared by every instance of the class, and accessible even without the need for an instance.
Java and several other languages have static variables, which have the same property of a single shared variable regardless of instances of the class and the possibility of access independent an any instance. However, there the key difference is with Python and Kotlin, this shared variable is also contained in an object, while a static variable has name scope within a class, but beyond that name, there is no relationship between a static variable and any object. An example of this difference is that a companion or class object can be part of a family of related classes and implement an interface or have inheritance or duck typing, allowing passing the object as parameter allowing code to operate on the class/companion variable without knowing the specific class.
Simply put, the companion/ class level object is a more object oriented approach that supports more metaprogramming.
Python supports both class methods and static methods. Static methods being an equivalent to other static methods in that they have name scope, but have no other relationship with any object.
Kotlin has companion object methods with are similar to python class methods, in that they have access to the object containing all settings, class variables and methods. They are just like instance methods, but operation on a companion type, or type object, in place of operation on an instance of the class itself.
Terminology for Clarity: Class Level Object, Variables and Methods
The python term ‘class method’ or ‘ class variable’ has a very high protentional for confusion with regular instance variables or instance methods.
The proposal current in use within this bliki is to use the term ‘class level method‘ or ‘class level variable‘. Another contender in place of ‘level’ was ‘singleton’ but the simpler level is the choice…at least for now.