How to initialize data to variable with same name as constructor variables? - kotlin

I have a variable foo:String declared in Kotlin and in constructor I want to pass variables with same name as foo:String but I don't know how to make both variables different from each other as in C# we use this.foo for class variables
I am expecting:
class Product
{
lateinit var productName:String
constructor(productName:String)
{
this.productName = productName
}
}
Please guide me how to do it in Kotlin.

That entire class can be written as just
class Product(var productName: String)

You use this like you used in C#
This sample shows how to do this for primary constructor
class Product{
private val name : String
constructor(name : String) {
this.name = name
}
}
And this is sample for second constructor:
class Product (){
private var name : String = ""
constructor(name : String) : this() {
this.name = name
}
}

Related

what is default value type of kotlin class constructor parameter?

class Greeter(name: String) {
fun greet() {
println("Hello, $name")
}
}
fun main(args: Array<String>) {
Greeter(args[0]).greet()
}
for above program I got this error
Unresolved reference: name
but when I add var or val
class Greeter(var name: String) {
or
class Greeter(val name: String) {
then program works fine, so why I need to add var or val to name, what is default type for constructor parameter val or var and why program gives me error when I not mention var or val
To use your value in the constructor like class Greeter(name: String), you can use init{}
class Greeter(name: String) {
var string:name = ""
init{
this.name = name
}
fun greet() {
println("Hello, $name")
}
}
or If you use val or var in the constructor it is more like class level variable and can be accessed anywhere inside the class
class Greeter(var name:String){
fun greet() {
println("Hello, $name")
}
}
The variable name can be used directly in the class then.
We can also give default values for the variables in both cases.
Adding val or var makes the parameter a property and can be accessed in the whole class.
Without this, it is only accessible inside init{}
The question is not making any sense, But the problem you are facing does make sense. In your case, the approach you are using is,
Wrong-Way:
// here name is just a dependency/value which will be used by the Greeter
// but since it is not assigned to any class members,
// it will not be accessible for member methods
class Greeter(name: String) {
fun greet(){} // can not access the 'name' value
}
Right-Way:
// here name is passed as a parameter but it is also made a class member
// with the same name, this class member will immutable as it is declared as 'val'
class Greeter(val name: String) {
fun greet(){} // can access the 'name' value
}
You can also replace val with var to make the name a mutable class member.

`java.lang.StackOverflowError` when accessing Kotlin property

I got this (contrived) sample from Packt's "Programming Kotlin" on using secondary constructor with inheritance.
Edit: from the answer it is clear that the issue is about backing field. But the book did not introduced that idea, just with the wrong example.
open class Payment(val amount: Int)
class ChequePayment : Payment {
constructor(amount: Int, name: String, bankId: String) : super(amount) {
this.name = name
this.bankId = bankId
}
var name: String
get() = this.name
var bankId: String
get() = this.bankId
}
val c = ChequePayment(3, "me", "ABC")
println("${c} ${c.amount} ${c.name}")
When I run it this error is shown.
$ kotlinc -script class.kts 2>&1 | more
java.lang.StackOverflowError
at Class$ChequePayment.getName(class.kts:10)
at Class$ChequePayment.getName(class.kts:10)
at Class$ChequePayment.getName(class.kts:10)
Line 10 does seems to be a infinite recursion, how to solve it?
You have a recursion in your code:
class ChequePayment : Payment {
constructor(amount: Int, name: String, bankId: String) : super(amount) {
this.name = name
this.bankId = bankId
}
var name: String
get() = this.name // recursion: will invoke getter of name (itself)
var bankId: String
get() = this.bankId // recursion: will invoke getter of bankId (itself)
}
If you don't need custom logic for your getter, just leave your properties like this:
var name: String
var bankId: String
They will have a default getter, which does nothing more than returning the value of the backing field.
Note: The code as it is can/should be refactored to this:
class ChequePayment(amount: Int, var name: String, var bankId: String) : Payment(amount) {
// ...
}
This uses the primary constructor and is much less redundant.
To access the backing field you have to use the keyword field instead of this.name see https://kotlinlang.org/docs/reference/properties.html#backing-fields
this.name references the getter, which references this.name which is an infinite recursion, as you already noted. In code:
var name: String
get() = field
var bankId: String
get() = field
Side note: Android Studio and Idea will complain rightfully that you don't need a getter in this case. So you can simplify even more:
var name: String
var bankId: String

How to assign new value if you setting the setter private in kotlin?

I am new in kotlin and not able to understand how the getter and setter behave in kotlin, so if I set the setter to private. Then what is the way of updating the value.
package foo
class Person() {
var name: String = "defaultValue"
private set
}
If you set your setter to be private, then this setter will be accessible only from within its class. In other words you can use normal assignment even when your setter is private but only from within the class.
class Person() {
var name: String = "defaultValue"
private set
fun foo(bar: String) {
name = bar // name can be set here
}
}
fun main(args: Array<String>) {
Person().name = "foo" // error. Name can be accessed but can not be modified here as its setter is private.
}
For more information check the Kotlin's Visibility documentation.
the kotlin code above will be transform to java code by kotlin compiler more like as below:
package foo;
public final class Person{
private String name = "defaultValue";
public final String getName(){
return name;
}
private final void setName(String name){
this.name=name;
}
}
which means you can only change the name field in the Person class. another situation is if you want to modify the name property with private setter out of the Person class. you can using java reflection instead, for example:
val person = Person();
val field = Person::name.javaField!!.apply { isAccessible = true }
field.set(person, "bob")
println(person.name)// "bob"
val setter = Person::class.java.getDeclaredMethod("setName", String::class.java)!!
.apply {
isAccessible = true
}
setter.invoke(person, "john")
println(person.name)// "john"

What is the difference between properties and parameters in Kotlin?

Here is a simple example of a class with some code (properties) inside the bracket
class Person(firstName: String) {
....
}
Now here is an example of a function with some code (parameters) inside the bracket
fun double(x: Int) {
...
}
I know this is a fundamental question but I am quite confused as a beginner.
You pass parameters to functions and constructors, and classes have properties.
The constructor of the Person class in your example has a single parameter, and so does the double function. In this case, the firstName parameter is not a property!
To make it a property, you have to declare it so:
class Person(firstName: String) {
val firstName : String = firstName
}
Kotlin allows this to be shorter, which makes the firstName parameter serve as a property:
class Person(val firstName: String)
First, your firstName also is a parameter rather than a property in Person class.
// v-- a parameter declared on primary constructor
class Person(firstName: String)
you can access a parameter declared on primary constructor in init block or property/field declaration, for example:
class Person(firstName: String){
val first:String
init{ first=firstName }
}
class Person(firstName: String){
val first:String = firstName
}
class Person(firstName: String){
#JvmField val first:String = firstName
}
to make the firstName to a property you can using keyword val or var, for example:
// v--- immutable property
class Person(val firstName: String)
// v--- mutable property
class Person(var firstName: String)
a Kotlin property will generate getter/setter(?) and a backing field(?) to java byte code. Take an example of a mutable property to java byte code as below:
public final class Person{
private String firstName; // backing field
// v--- parameter
public Person(String firstName){ this.firstName = firstName; }
//getter
public final String getFirstName(){ return firstName; }
//setter
public final String setFirstName(String firstName){ this.firstName= firstName; }
}
a parameter only visible in function scope/constructor scope except parameter declared on primary constructor.
Note: a parameter is immutable like as java effective-final variables/parameters, so you can't reassign a parameter at all in Kotlin, for example:
fun foo(bar:String){
bar = "baz"
// ^--- compile error
}
properties and parameters are different thinks:
parameters : when we declare any function :
fun sum(a: Int, b: Int): Int {
return a + b
}
Function having two Int parameters with Int return type:
Properties and Fields:
Declaring Properties
Classes in Kotlin can have properties. These can be declared as mutable, using the var keyword or read-only using the val keyword.
class Address {
var name: String = ...
var street: String = ...
var city: String = ...
var state: String? = ...
var zip: String = ...
}
To use a property, we simply refer to it by name, as if it were a field in Java:
fun copyAddress(address: Address): Address {
val result = Address() // there's no 'new' keyword in Kotlin
result.name = address.name // accessors are called
result.street = address.street
// ...
return result
}
The full syntax for declaring a property is:
var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]

Why use this when accessing a private method?

I have a question regarding oop. It might seem really trivial. I have seen example online where they use this to access a private method. Is it really necessary? Is it language specific?
Here is an example which can be done with or withour this.
class A {
def test(): String = {
val x = this.test_2()
x
}
private def test_2(): String = {
"This is working"
}
}
object Main extends App {
val a = new A
val x = a.test
println(x)
}
Here the same code without this. both are working.
class A {
def test(): String = {
val x = test_2()
x
}
private def test_2(): String = {
"This is working"
}
}
object Main extends App {
val a = new A
val x = a.test
println(x)
}
Some languages won't accept the use of a method without the this, like python (self.), but in most case, it's a matter of readability and safety.
If you define a function out of the class with the same name as a method of the class, it can cause a problem.
By adding this, you know it's a method from the class.
The "this" keyword refers to the class which you are currently writing code in it. It is mainly use to distinct between method parameters and class fields.
For example, let's assume you have the following class:
public class Student
{
string name = ""; //Field "name" in class Student
//Constructor of the Student class, takes the name of the Student
//as argument
public Student(string name)
{
//Assign the value of the constructor argument "name" to the field "name"
this.name = name;
//If you'd miss out the "this" here (name = name;) you would just assign the
//constructor argument to itself and the field "name" of the
//Person class would keep its value "".
}
}