contents:
- self vs this
- this@
- external attribute access
- why bother?
- python modifiers
- visibility
- inheritance: open, final, override
- inline
self vs this
Self vs this are not technically modifiers, but they do work in a similar way, to modify that ‘self.name’ can be different from ‘name’.
Code inside a class must work without an actual instance object name, so a naming convention is requited. The naming convention to indicate the current object in python is self, and the equivalent for Kotlin is this.
The python self is needed throughout class definitions, as the first parameter for every method, and as a qualifier for every access to a method or field or other attribute within the class.
The kotlin this is a keyword, not a convention, and is not the first parameter for method definitions. Kotlin can have this as a qualifier for access to fields and methods within the class, but is only required when there is a local of the same name. So while self seems to occur everywhere in Python, this is used very rarely in Kotlin.
# consider in method definition in a python class
def setNames(self, name): # self as first parameter
self.name = name
self.otherName = ""
self.fullName = name # use name as fullname
In fact self in Python is a convention, not a reserved word. The same code above would work perfectly if every ‘self‘ is replaced by ‘this‘. Or even if every ‘self‘ is replaced by ‘confuse_everyone‘. Clearly this is not a good idea, but it does work!
//method definition within a kotlin class
fun setNames(name: String){ // 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'
}
In Kotlin ‘this‘ is a reserved word, even though ‘this‘ is rarely needed. In the above example there is both a parameter ‘name‘ and an object field ‘name‘. Using ‘this.name‘ for the object field is required to avoid ambiguity. The keyword ‘this‘ is only rarely required, but is optional for otherName and fullName as well. Kotlin allows ‘this.‘ for any attribute, but ‘this‘ is only needed when there is a local or parameter with the same name as the class attribute.
this@
There can actually be more than one ‘this’ context active at one time. When there are more than one this context, the ‘this@’ form is used. Within a class, this@<class-name> will is used to ensure the correct this for that class. Within an extension function, this@<function-name> will refer to the class being extended. It may be useful to always have the @ whenever this is required.
External Access to Class Attributes
Access to variables of an object from outside the code of class definition is the same for python and kotlin. Consider the code in the discussion on setters and getters. The code p1.name will access the name variable from the object p1 in that example.
Modifiers: Why bother?
Modifiers do to things, they tell the language the intent of code, and the tell the reader the intent of code. The mistake is to think of modifiers like private as keeping data secure. There is always a way around these if someone really wants to get around them, hence the python approach as outlined below. In fact, in python, libraries usually distributed as source code, so the user of the library can change the access if they want anyway. Even in Kotlin, the person being ‘restricted’ in access by visibility, very often has access to the code with the modifier.
So modifiers are to communicate intent, not enforce intent.
If the program will only be read by the same person who wrote the program, then why both with modifiers? The same as ‘why bother with readable variable names?’.
With Kotlin, the communication is also to the language. A public attribute often generates more code than a private attribute, and if there is no access from outside the object, that code may never used. The amount of code is very small. So the gains in object code from modifiers are in generally insignificant…. unless producing extremely speed critical or size critical code…and in that rare case it can matter a lot.
The general rule is: think of modifiers like self testing comments. Dont add them without reason, but at least what they say is checked to be true, unlike comments. But again, do not add modifiers without reason, just as a comment should not be added if the comment does not mean anything.
Python visibility modifiers.
Python has two visibility modifiers: a leading underscore, and two leading underscores.
One leading underscore in python to simply signal to anyone reading the code that the attribute to be for internal use within the class. So _name (with leading underscore) is for internal use and name is for external use. How the attribute works is unchanged so an the attribute is available for unit tests, debugging etc or …. not following that original intent.
One leading underscore in Kotlin is the same convention for Kotlin, but is normall only used when both the name with and without the underscore are to be used in the class. For example, name as the property with getter and setter, _name as the internal backing field.
Two leading underscores in Python actually does make the name invisible from outside the class, but using an encoded name. This makes an effective equivalent to private.
visibility: public, private, protected and internal
Kotlin follows the Python philosophy of all attributes being public by default, and allowing a leading underscore to indicate that privacy should be respected but is not enforced. This is the opposite of Java and C# and other languages which have private as the default visibility. However Kotlin, does also support enforced visibility restrictions.
public: The p1.name example works because name is public. In both python and kotlin, all object attributes are public by default, so there only a need for the public modifier, within a scope that has another modifier already, such as within a protected inner class. Since public is the default, using the modifier is usually about documenting the intent for the attribute to be public. Public means accessible from anywhere the as long as there is reference to the object.
private: Kotlin has the reserved word ‘private’ to indicate an attribute inaccessible from outside the class declaration. While both languages have a convention of a leading underscore indicating an attribute which is hinted should be considered private but without actual restrictions, Python uses a double leading underscore to actually restrict access. (this modifier also works outside classes)
protected: Kotlin also has protected which means accessible within subclass code as well as the code of the class itself.
internal: Kotlin adds another visibility modifier, ‘internal‘, which means accessible only from with the same source file. (this modifier also works outside classes)
Inheritance Modifiers: open & override, final
Open gives permission for subclasses override. Requiring these modifiers for overriding is to prevent accidental overriding. Their existence in Kotlin and not python is about the bias of Kotlin towards large team projects, and Python towards individual projects. I mean, if you write both the class and the subclass, then these only get in the road. Fortunately, a smart IDE can allow one click to enable both, reducing the effort to a level that fits the payback in readability. Beyond readability, there is a payback in keeping machine code concise and high performance in defaulting to not being open.
Final, the default, is the opposite of open. Override methods are open by default, so this is the main use case for the modifier, other than to specifically declare to a reader that something should be kept final.
static, class method
to be added
Inline
These means that in place of a function call, the code for the operation will be included every time the function call appears in the program. This also allows special functionality but, In terms of this bliki, there is little to add standard documentation: inline.
[…] visibility modifiers: unusual, but effective […]
LikeLike