# 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

is’ operator checks the type of variable and returns boolean as true if it matches the type.

`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

In other programming languages, the variable requires an explicit casting on the variable before accessing the properties of that variable but Kotlin does a smart casting. The compiler automatically converts the variable shapeObject to a particular class reference once it’s passed through any conditional operator.

`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’

as’ operator works as other languages cast operators which casts the object to another object with particular reference.

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

--

--