2

I have stared Kotlin recently and have experience in Java. In Java, we can declare the field with same name as it is in parent. When I do same in Kotlin it gives error name hides member of Super type User. What am I missing here?

Kotlin

open class User(protected var name: String)

class TwitterUser(var name: String) : User(name)

Same concept for Java

public class A {
    protected String name;
}

public class B extends A {
    String name;
}
mallaudin
  • 4,744
  • 3
  • 36
  • 68
  • 1
    Techically doing that is Java *also* hides the member of the super type, Java's compiler just doesn't error out you when that happens... but it probably tosses a warning at you. – Powerlord Dec 30 '17 at 10:40
  • [Unlike Java](https://kotlinlang.org/docs/reference/classes.html#overriding-methods), Kotlin requires explicit annotations for overridable members and for overrides. – BakaWaii Dec 30 '17 at 11:46

3 Answers3

1

Change it like,

open class ClassParent(name: String) {

}

class ClassChild(name: String) : ClassParent(name) {

}

you can use init block, check details

Amit Vaghela
  • 22,772
  • 22
  • 86
  • 142
  • I know it will work like this. But why the above code gives error? – mallaudin Dec 30 '17 at 10:36
  • it doest override member of parent and you need to override because you are extening parent class so it show this error – Amit Vaghela Dec 30 '17 at 10:41
  • @mallaudin The initial error is because a data class can't have parameters in its primary constructor other than val or var properties. Removing the data keyword lifts this restriction. – Amit Vaghela Dec 30 '17 at 10:42
  • @mallaudin please check https://stackoverflow.com/a/44129826/2826147 and https://stackoverflow.com/questions/44419997/extending-data-class-from-a-sealed-class-in-kotlin – Amit Vaghela Dec 30 '17 at 10:42
1

The issue is, that you're hiding the implementation of the original property. But there's one possibility to do so anyhow:

open class User(protected open var name: String)

class TwitterUser(override var name: String) : User(name)

You just have to consider, that this mainly changes the implementation of the property. You will not be able to access User.name or TwitterUser.name separately. It's just the same.

tynn
  • 38,113
  • 8
  • 108
  • 143
1

If your superclass already has a name property, any subclass will have it automatically, too. Why would you then define it again in that child? It's better to simply define it as a parameter of the constructor without making it another property:

open class User(protected var name: String)
//name is not a val/val! simply passed to the constructor as an argument
class TwitterUser(name: String) : User(name)

Otherwise, if you really need to override that property, make it open in the parent and override in the child:

open class User(protected open var name: String)
class TwitterUser(override var name: String) : User(name) 
s1m0nw1
  • 76,759
  • 17
  • 167
  • 196