The Programmers Guide To Kotlin - The Class & The Object
Written by Mike James   
Tuesday, 29 October 2024
Article Index
The Programmers Guide To Kotlin - The Class & The Object
Secondary Constructors
Late Initialized Properties
Static Members & Companion Objects
Object Expressions
Value Classes

The value class allows you to create your own classes that behave like the ones used for primitives. A value class, formerly known as an inline class, can only represent a single value and has no identity.

For example;

@JvmInline
value class Color(val rgb: Int)

defines a value class that wraps a single Int value. The annotation is needed for the JVM target and might well be dropped in the future.

The first important point to note is that, as far as the programmer is concerned, the Color class behaves like any other. So, for example, to print its value you would use:

val col=Color(0x0FF)
println(col.rgb)

and in this case clearly only an Int is passed to the println function.

Now consider:

fun displayColor(c:Color){
    println(c.rgb)
}
fun main() {
    val col = Color(0x0FF)
    displayColor(col)
}

In this case the Color object is being passed to the displayColor function. What do you expect to be actually passed to displayColor? The answer is that the compiler notices that all that is used in the function is the wrapped value and therefore only passes the wrapped value. That is displayColor is actually implemented as;

fun displayColor(c:Int){
    println(c)
}
displayColor(col.rgb)

Thus we have avoided creating a wrapper object and passing it to the function. The compiler will always prefer to use the wrapped type, i.e. the value, rather than the wrapper type. This is what value classes are all about.

You can include an init block and properties within the value class. but if you use any of them then the value is boxed by the wrapper when they are used.

Value classes cannot be part of the inheritance hierarchy, but they can inherit from an interface – see the next chapter:

@JvmInline
value class Color(val rgb: Int) {
    init {
        if(rgb>0xFFF) println("error")
    }
    val red: Int
        get() = rgb/0x100
    fun printRed() {
          val hexRed=Integer.toHexString(red)
          println("red, $hexRed")
    }
}
fun main() {
    val col = Color(0xFFF)
    println(col.rgb)
    col.printRed()
}

Value classes are sure to evolve further, but their use is relatively limited and motivated by efficiency rather than elegance. They might be more generally useful when extended to wrapping multiple values. In this case they would look a lot like what is called a struct in C, C++ or C#.

Summary

  • Every class has a primary constructor, even if it is just the default parameterless constructor provided by the system.

  • The primary constructor is just a declaration of parameters that can be used when an instance is created.

  • You can use the parameters within the properties and methods defined in the class definition.

  • Usually the parameters in the primary constructor are used to automatically create properties using var or val.

  • You can delegate properties to other objects,

  • If you want to do more in the constructor, or have overloaded constructors, you need to define secondary constructors.

  • Secondary constructors have a method body and can execute code.

  • A secondary constructor always has to call the primary constructor using the this(parameters) statement.

  • A class can also have any number of initializer blocks, which are executed after the constructor is called, but before any constructor body is executed.

  • Value classes work like custom wrappers for primitive values. The compiler uses the primitive type whenever possible.

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner


Kotlin Ktor Improves Client-Server Support
04/11/2024

Kotlin Ktor 3 is now available with better performance and improvements including support for server-sent events and CSRF (Cross-Site Request Forgery) protection.



IBM Updates Granite Models
28/10/2024

IBM has released new Granite models that it says provide state-of-the-art performance relative to model size. The Granite 3.0 collection includes a new, instruction-tuned, dense decoder-only LLM.


More News

espbook

 

Comments




or email your comment to: comments@i-programmer.info



Last Updated ( Tuesday, 29 October 2024 )