Real World Example

Shopping Cart for an E-commerce App

Apps like Flipkart and Myntra keep a cart object in memory. The cart validates input in init/methods, exposes read-only computed properties, and hides its internal list.

Example

class CartItem(val name: String, val price: Double, quantity: Int = 1) {
    var quantity = quantity
        set(value) {
            require(value in 1..10) { "Quantity must be 1-10" }
            field = value
        }
    val total get() = price * quantity
}

class Cart(val userId: String) {
    private val items = mutableListOf<CartItem>()

    val itemCount get() = items.sumOf { it.quantity }
    val subtotal get() = items.sumOf { it.total }
    val deliveryFee get() = if (subtotal >= 499) 0.0 else 40.0

    fun add(item: CartItem) { items.add(item) }

    fun printBill() {
        items.forEach { println("%-12s x%d  %8.2f".format(it.name, it.quantity, it.total)) }
        println("Items: $itemCount, Subtotal: $subtotal, Delivery: $deliveryFee")
        println("Pay: ${subtotal + deliveryFee}")
    }
}

fun main() {
    val cart = Cart("user-42")
    cart.add(CartItem("T-Shirt", 299.0))
    val socks = CartItem("Socks", 99.0)
    socks.quantity = 2
    cart.add(socks)
    cart.printBill()
}

Output

T-Shirt      x1    299.00
Socks        x2    198.00
Items: 3, Subtotal: 497.0, Delivery: 40.0
Pay: 537.0

Android: lateinit in an Activity

In Android you cannot create views or bindings in the constructor; they are ready only in onCreate(). That is the classic use of lateinit.

class ProductActivity : AppCompatActivity() {

    private lateinit var binding: ActivityProductBinding
    private val viewModel: ProductViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityProductBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.addToCartButton.setOnClickListener {
            viewModel.addToCart()
        }
    }
}

Tip: Prefer constructor parameters and val. Use lateinit only when a framework (Android, dependency injection, test setup) gives you the value after construction.