# TypeCheck (‘is’) and Cast (‘as’) in Kotlin

`This post was originally posted at https://agrawalsuneet.github.io/blogs/typecheck-is-and-cast-as-in-kotlin/ and reposted on Medium on 24th Nov 2017.`
`interface Shape {     fun calculateArea(): Float}`
`class Circle : Shape {    var radius: Float = 10.0f    override fun calculateArea(): Float {       return (22 * radius * radius) / 7    }}class Square : Shape {    var sideLength: Float = 10.0f    override fun calculateArea(): Float {       return sideLength * sideLength    }}class Rectangle : Shape {    var length: Float = 10.0f    var breadth: Float = 5.0f    override fun calculateArea(): Float {       return length * breadth    }}`
`var shapeObject: Shapeif (/* Some Condition*/) {    shapeObject = Circle()} else if (/* Some Other Condition*/) {    shapeObject = Square()} else {    shapeObject = Rectangle()}`
`shapeObject.radius = 10.0f //compile time error`

## ‘is’ and ‘!is’ Operators

`if (shapeObject is Circle) {    print(“it’s a Circle”)} else if (shapeObject is Square) {    print(“it’s a Square”)} else if (shapeObject is Rectangle) {    print(“it’s a Rectangle”)}`
`if (shapeObject !is Circle) {    print(“it’s not a Circle”)} else if (shapeObject !is Square) {    print(“it’s not a Square”)} else if (shapeObject !is Rectangle) {    print(“it’s not a Rectangle”)}`

## Smart Casts

`var area: Float = 0.0fif (shapeObject is Circle) {    shapeObject.radius = 10.0f //compiles fine    area = shapeObject.calculateArea()} else if (shapeObject is Square) {    shapeObject.sideLength = 5.0f //compiles fine    area = shapeObject.calculateArea()} else if (shapeObject is Rectangle) {    shapeObject.length = 10.0f //compiles fine    shapeObject.breadth = 5.0f //compiles fine    area = shapeObject.calculateArea()}`
`if ( shapeObject !is Circle) returnshapeObject.radius = 3.0f /*compiles fine as the non Circle class reference were already returned*/area = shapeObject.calculateArea()`
`/* Automatically cast the right-hand side of && to Circle */if (shapeObject is Circle && shapeObject.radius > 5.0f){    print(“Circle with radius more than 5.0”)}/* Automatically cast the right hand side of || to Sqaure */if (shapeObject !is Square || shapeObject.sideLength < 3.0f){    print(“Either not square or is a square with side length less than 3.0f”)}`
`when(shapeObject){    is Circle -> shapeObject.radius = 3.0f    is Square -> shapeObject.sideLength = 4.0f    is Rectangle -> {       shapeObject.length = 5.0f       shapeObject.breadth = 6.0f    }    else -> print(“Undefined type”)}var count = 0while (count < 5 && shapeObject is Circle){    shapeObject.radius = count.toFloat() //compiles fine    area += shapeObject.calculateArea()}`
• val local variables — always;
• val properties — if the property is private or internal or the check is performed in the same module where the property is declared. Smart casts aren’t applicable to open properties or properties that have custom getters;
• var local variables — if the variable is not modified between the check and the usage and is not captured in a lambda that modifies it;
• var properties — never (because the variable can be modified at any time by other code).

## Explicit Cast operator ‘as’

`var otherShapeObject = shapeObject as Circle`
`var nullableShapeObject : Circle? = shapeObject as Circle?`
`var safeCastObject : Circle? = shapeObject as? Circle`

--

--

--

## More from Suneet Agrawal

https://agrawalsuneet.github.io/

Love podcasts or audiobooks? Learn on the go with our new app.

## Suneet Agrawal

https://agrawalsuneet.github.io/