
🛒 Narrowing Reference Conversion and Disjoint Types – with Carrefour Shops
Explained with Carrefour Shops 🛒
In Java, narrowing reference conversion is used in type casts when you're converting from a broader type to a more specific one — even if there's no direct inheritance relationship between the types. This allows more flexibility, but also brings some risks at runtime, so the compiler applies smart checks — especially with sealed classes and final classes — to avoid impossible casts.
Let’s understand this using a theme inspired by Carrefour store types. Imagine Carrefour runs various specialized store formats: Carrefour City, Carrefour Market, Carrefour Drive, etc.
✅ Valid Cast: Subtypes Are Compatible
This works fine! CarrefourMarket is a subtype of CarrefourShop, so the cast is straightforward.
⚠️ Cast Between Unrelated Types: Technically Allowed, but Risky
Even though CarrefourExpress doesn't implement CarrefourShop, the compiler allows this cast because, in theory, someone could later write:
So at runtime, it might succeed if the object is actually of type HybridStore.
❌ Invalid Cast: Disjoint Types
This cast will never work. CarrefourBankingApp is final, so it can’t be extended. Since it doesn’t implement CarrefourShop and can't ever do so, the compiler knows the types are disjoint and blocks the cast.
🔐 Sealed Classes Help the Compiler Decide
Here’s what happens:
🟣 RetailEntity is a sealed interface, and only CarrefourShop can extend it.
🟣 CarrefourBankingApp is a final class that cannot be extended to fit into the hierarchy of RetailEntity.
🟣 The cast to CarrefourBankingApp is statically rejected.
🟣 But CarrefourOnline is not final. It’s possible (at least theoretically) that someone could define:
So the cast is allowed.
☝️ Summary
Using sealed classes and final wisely helps the compiler prevent you from making dangerous casts, and ensures more reliable, type-safe code — even in a supermarket chain! 🧾