How does Kotlin's protected modifier behave, and how does it differ from Java's protected?
answer
- protected = class + subclasses only
- No package access (unlike Java)
- Illegal at top level
- Overrides can widen, not narrow
- Kotlin protected is tighter than Java's
basics
~10 sKotlin's protected makes a member visible to the class and its subclasses only. Unlike Java, it does NOT add package-wide visibility, and it can't be used on top-level declarations.
solid answer
~40 s`protected` in Kotlin means a member is visible inside the **declaring class and its subclasses** — and nothing else. It cannot be applied to **top-level** declarations (there's no class to subclass). The big difference from Java: Java's `protected` *also* grants **package-private** access, so any class in the same package can touch a protected member even without inheritance. Kotlin removed that package dimension, so Kotlin `protected` is strictly *inheritance-based*. Another subtlety: when you **override** a `protected` member you may keep it `protected` or widen it (e.g., to `public`); you cannot narrow it further. Also, a subclass can access the protected member only **through the subclass's own type hierarchy**, not via an arbitrary superclass reference in some unrelated context. Because there's no package leakage, Kotlin `protected` is a genuinely tighter contract than Java's.
go deeper
Knows protected exposes a member to subclasses.
Knows protected has no package dimension in Kotlin and can't be top-level.
Explains override widening/narrowing rules and Java-interop migration consequences.
Weighs protected vs internal for designing extensible base classes and stable inheritance contracts across modules.
## What `protected` means in Kotlin `protected` makes a member visible to: - the **declaring class**, and - **subclasses** of that class. It is **not** visible to unrelated classes, and it **cannot** be applied to top-level declarations (a top-level function/property has no class, so 'subclass' is meaningless — the compiler rejects it). ```kotlin open class Shape { protected open val sides: Int = 0 protected fun describe() = "sides=$sides" } class Triangle : Shape() { override val sides = 3 // can see & override protected fun label() = describe() // OK: subclass call } // outsideCode() { Shape().describe() } // ERROR: protected, not accessible ``` ## The Java difference (the key interview point) In **Java**, `protected` grants access to subclasses **and** to every class in the **same package** (it is effectively `protected` + package-private). In **Kotlin**, `protected` grants access to subclasses **only** — there is no package component, because Kotlin has no package-private visibility at all. So porting Java code that relied on protected-via-same-package access will break; you'd switch those usages to `internal` or `public`. | Access from… | Java protected | Kotlin protected | |---|---|---| | Declaring class | yes | yes | | Subclass | yes | yes | | Same-package non-subclass | **yes** | **no** | | Anywhere else | no | no | ## Overriding rules When overriding a `protected` member, the override **keeps protected by default** but may **widen** visibility (to `public`). It may not become more restrictive (you can't override a protected member as private). This mirrors the Liskov rule that overrides cannot tighten access. ```kotlin open class Base { protected open fun f() {} } class Sub : Base() { public override fun f() {} } // widened: allowed ``` ## Where it can't go - **Top-level** declarations: compile error. - **Members of a `final` (non-`open`) class**: legal syntactically but pointless, since the class can't be subclassed; the compiler may warn. ## Recall - Kotlin `protected` = class + subclasses, **no package access**. - Java `protected` = class + subclasses **+ same package**. - Not allowed at top level; overrides may widen, not narrow.
- Can you declare a protected top-level function?No — the compiler rejects it because there is no enclosing class to be subclassed.
- When overriding a protected method, what visibilities are allowed?You can keep it protected or widen to public; you cannot narrow it to private or internal in a way that reduces access.
Kotlin protected is a family heirloom passed only down the bloodline; Java's also lets the neighbors (the package) borrow it.
saying these in an interview costs you the question
- Claiming Kotlin protected grants package access like Java
- Saying protected works on top-level declarations
- Thinking an override can narrow protected to private
- Confusing protected with internal
- Believing protected members are visible to any same-module class