Why use this when accessing a private method? - oop

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 "".
}
}

Related

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

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
}
}

How to change return type based on a function input which is a class name?

I have multiple data classes and each class has a corresponding class containing more info. I want to write a function in which I should be able to pass an identifier (table name corresponding to the data class). Based on this identifier, object of the corresponding class should be made, the value changed and this object should be returned as output of the function. I have written a simplified version of it on playground but I am unable to get it to work. Any help is appreciated.
class someClass(
)
class objectForSomeClass(
var value: String
)
class someOtherClass(
)
class objectForSomeOtherClass(
var value: String
)
class doSomething() {
companion object {
val classMap = mapOf(
"someClass" to objectForSomeClass::class,
"someOtherClass" to objectForSomeOtherClass::class,
)
}
// Create a map of class name to a new object based on the class name input
fun dummyFun(className: String, valueInput: String): Map<String, kotlin.Any> {
var returnObject = mutableListOf<Pair<String, kotlin.Any>>()
when(className) {
"SOME_CLASS" -> {
returnObject = mutableListOf<Pair<String, justDoIt.classMap["someClass"]()>>()
}
"SOME_OTHER_CLASS" -> {
returnObject = Map<String, justDoIt.classMap["someOtherClass"]()>
}
}
returnObject[className].value = valueInput
return returnObject
}
}
fun main() {
var obj = doSomething()
var t = obj.dummyFun("SOME_CLASS", "Value to be inserted")
// do something with t
}
Not knowing more about your classes (the ones in your code are not data classes – a data class in Kotlin is a specific type of class) I still think a lot could be simplified down to maybe even this:
fun createObject(className: String, value: String): Any? {
return when (className) {
"SomeClass" -> ObjectForSomeClass(value)
"SomeOtherClass" -> ObjectForSomeOtherClass(value)
// ...
else -> null
}
}
Additionally:
The classMap is not necessary, you can hard-code the cases in the when clause as in my example. There is also no need for reflection, which you would need to create instances from SomeType::class.
With getting rid of classMap you also do not need the companion object holding it anymore, and then you are left with one function for creating instances of your classes, and this function does not have to be in a class. You might put it into a singleton class called object in Kotlin (https://kotlinlang.org/docs/object-declarations.html#object-expressions)
Data classes in Kotlin: https://kotlinlang.org/docs/data-classes.html
You could maybe also replace each class someClass & class objectForSomeClass pair with a class someClass with a companion object.

Kotlin, how to assign callback implementation to a variable

I'm trying to assign a callback implementation of an interface (defined inside a class A) to a variabile defined inside another class B. Let's say that class A has the interface OnSomethingHappens which defines a doSomething method.
Inside class B I've defined my callback variable like this:
private lateinit var callback:A.OnSomethingHappens
I need to create an instance of class A passing callback variabile to the constructor in this way:
myinstanceA = A(callback)
I'm trying to assign an instance of an anonymous class that implements A.OnSomethingHappens using this code:
callback = object : A.OnSomethingHappens {
override fun doSomething(..){
//here I put the implementation of this method
}
}
but the compiler says "expecting member declaration" for my callback variable and "name expected" for object.
What I'm doing wrong?
Instead, I'm able to define and at the same time assign the callback variable in this way:
private var callback = object : A.OnSomethingHappens {
override fun doSomething(..){
//here I put the implementation of this method
}
}
Why? Which are the differences and a possible solution?
I'm trying to assign an instance of an anonymous class that implements A.OnSomethingHappens using this code: ...
This should work, but only inside a method:
class B {
private lateinit var callback:A.OnSomethingHappens
fun someMethod() {
callback = object : A.OnSomethingHappens { ... }
}
...
}
Given the error message and that private var compiles (which doesn't inside a method), you are trying to set it directly in the body of the class instead:
class B {
private lateinit var callback:A.OnSomethingHappens
callback = object : A.OnSomethingHappens { ... }
...
}
This is illegal: the only code you can write there is member definitions and init blocks.
Also, if you can initialize callback directly where it's defined or inside init, there's no point to lateinit in the first place.
It's not obvious from the code snippets cut down to such small pieces, but your issue is that you're writing down the assignment inside the body of a class, but not inside a function.
Here's an example of a valid declaration and immediate assignment:
class A {
var x: X? = X()
}
Here's an example of an invalid assignment, which places an arbitrary expression in the body of a class:
class A {
lateinit var x: X
x = X() // expression placed inside the class body, invalid syntax
someFunction() // extra example, calling functions here is invalid in the same way
}
Instead, you could put this initialization inside a function:
class A {
lateinit var x: X
fun initializeX() {
x = X()
}
}
Or inside an initializer block (in this case, you don't even need lateinit):
class A {
var x: X
init {
x = X()
}
}
While I couldn't explain how to solve your exact problem, because I can't quite understand what code is in which class, I hope these examples and explanation helped.
Hmm, let me propose a variant. It's more simple for me:
import android.util.Log
class SomeClass {
fun mainMethod() {
ClassWithCallback(
{ myBackValue: String ->
logMyString(myBackValue)
}
)
//simplify
ClassWithCallback({ logMyString(it) })
}
private fun logMyString(myBackValue: String) {
Log.d("SomeClass", myBackValue)
}
}
class ClassWithCallback(private val myCallBack: (myBackValue: String) -> Unit) {
init {
// we do something here and back it by callback
val myString = "Hello! Pass me back!"
myCallBack.invoke(myString.toUpperCase())
}
}
Using Kotlin lambdas. Hope this will help you.

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"

Using class variables within an instance of a class

I'm trying to use Swift to create an instance of a class (the class being the desired type) but it would seem that when I initialize the instance the class var is not applied to the new instance. I'm sure there's an init call or something that I'm missing, so any help would be greatly appriciated.
class Person: NSObject {
private struct personNameStruct { static var _personName: String = "" }
class var personName: String
{
get { return personNameStruct._personName }
set { personNameStruct._personName = newValue }
}
}
var testPerson: Person
testPerson.personName = "Foo" //"'person' does not have a member named 'personName'"
An instance member is referred to through a reference to an instance.
A class member is referred to through a reference to the class.
So, for example:
class Dog {
class var whatDogsSay : String {
return "Woof"
}
func bark() {
println(Dog.whatDogsSay)
}
}
To make a dog bark, make a dog instance and tell it to bark:
let d = Dog()
d.bark()
To find out what dogs say, talk to the dog class:
let s = Dog.whatDogsSay
It works for me in a Playground if you access the personName variable using the class name person, not the instance name: person.personName = "Foo".
This is because a class variable in Swift is similar to a static variable in languages like Java and C#, in that it is shared between all instances of that class. If you just want a property in your class you shouldn't declare it as class var but just var.