This question already has answers here:
How to create an instance of anonymous class of abstract class in Kotlin?
(2 answers)
Closed 2 years ago.
In C# I can:
var a = new { prop42 = "42" };
Console.WriteLine("a.prop42 = " + a.prop42);
Or do some other things, like serialization anonymous class instances (for using in js in browser). No interfaces or abstract classes used, fully anonymous class instance.
It is possible to make same thing in Kotlin?
Yes, you can do the equivalent in Kotlin:
val a = object { val prop42 = "42" }
println("a.prop42 = ${a.prop42}")
It's described in the language reference. See also this question.
This isn't often a good idea, though. Because the type doesn't have a name, you can't use it in public declarations, such as class or top-level properties of that type; nor can you create lists or maps of it. (In general, you can only refer to its named superclass — Any in this case, since you didn't specify one.) So its use is a bit restricted. (The lack of a name also makes the code harder to follow.)
Related
If I have
sealed class Foo<A> {
data class Bar<A>(val value: Int): Foo<A>()
}
and I want to refer to the Bar<Int> constructor as an implicit lambda using the :: operator, then none of the following are accepted as valid syntax:
Foo<Int>::Bar<Int>
::Foo.Bar<Int>
::(Foo.Bar<Int>) (the compiler tells me that this syntax is reserved for future use).
I can refer to it if I explicitly import the nested class constructor into the scope using
import com.package.Foo.Bar
which allows me to write ::Bar for the constructor and Bar<Int>::value for the property getter. But I have to do this for every nested constructor, and it kind of defeats the advantage of using the :: operator to save typing.
Is there a notation that I have missed which allows me to avoid having to import all nested class names and constructors?
Edit
My original example did not involve generics, which turns out was an oversimplification of the problem I had in my actual code that I am working on, which does use generics.
It turns out that for nested classes without generic parameters, the Foo::Bar notation actually works, so my original question had a false premise. It is, however, not possible to create callable references to constructors within generic classes. This is documented in the following bug report: https://youtrack.jetbrains.com/issue/KT-15952
It is a known bug in the language design: https://youtrack.jetbrains.com/issue/KT-15952
This bug report did however lead me to another workaround using type aliases which is equivalent to adding aliased imports, but has the advantage that you can put the alias where you want, and even share it between modules. In summary, this is the two only viable solutions I know of so far:
// Method one: Import Foo.Bar
import Foo.Bar as BarImported
sealed class Foo<A> {
data class Bar<A>(val value: A): Foo<A>()
}
val ctor: (Int) -> Foo<Int> = ::BarImported
val getter: (BarImported<Int>) -> Int = BarImported<Int>::value
// Method two: Alias Foo.Bar
typealias BarAlias<A> = Foo.Bar<A>
val ctor2: (Int) -> Foo<Int> = ::BarAlias
val getter2: (Foo.Bar<Int>) -> Int = BarAlias<Int>::value
What about wild card imports?
import com.package.Foo.*
In the Kotlin docs, they show how to include type parameters:
class Box<T>(t: T) {
var value = t
}
This is a simple example. But I've come across one that looks like this:
abstract class SomeAdapter<T, WH: SomeViewHolder>(private val viewModel: SomeModel<T>?) {
}
How do I interpret this? Do I interpret this as:
SomeAdapter takes two parameters when it's instantiated - a T and a WH. And the constructor takes a viewModel.
As you already referenced, this class has two generic types: T and WH. The latter does specify an upper bound SomeViewHolder which will only allow sub types of that upper bound to be used as the generic type WH.
Since your title goes:
Understanding generic parameters in an abstract class
the question at hand is: Would it be different (regarding the generic types) if SomeAdapter would not be abstract. The answer is: No.
In this particular example T can be Any? and WH can be any subclass of SomeAdapter or SomeAdapter itself (if SomeAdapter is not abstract).
The types of T and WH are fixed at compile time (see Type erasure).
So, you have to see generics like a variable for a type.
I am currently practicing in developing kotlin and as of now I seem to get confused with kotlin's class structure.
this is a code in java
//properties
private String var;
//constructor
public SampleClass(String var){
this.var = var;
}
public SampleClass(){
}
//getters and setters
public String getVar(){
return this.var;
}
public String setVar(String var){
this.var = var;
}
what's the kotlin equivalent of this ?
This is the equivalent Kotlin code for your Java code:
class SampleClass(var `var`: String? = null)
There are a few things to note:
Your Java snippet above omits the wrapping class SampleClass code
Your setVar() indicates that it returns a String, but it's actually void. I assume you intended for it to have a void return type.
Your property var is not ideal for Kotlin, because it's a reserved word. That's why we have to escape it with backticks. (It could also be kind of confusing in Java 10, since var is a reserved type name there now).
Here's why this one-liner is equivalent to the Java listing.
The constructor part - the part between the parentheses - can be used to accept constructor arguments, but by putting the Kotlin keyword var at the beginning, we tell Kotlin that we want this to also be a property. Kotlin will create a getter and setter for it.
The String? part makes this property of type nullable String.
Instead of creating two different constructors, we just give our var property argument a default value of null by using = null. When creating this class from Java, it'll still show up as two constructors.
If you're using IntelliJ or Android Studio, you can tell it to convert any Java class to Kotlin. Just open the class file, and go to the Code menu, and choose Convert Java file to Kotlin file. It won't necessarily generate very idiomatic code (e.g., it might create two constructors instead of using a default for the constructor argument), but it'll get you started.
For "what is Kotlin equivalent of some code in Java", there is an universal answer: copy the Java code and paste it into a Kotlin file in IDEA/Android Studio. Or convert the entire file.
On the web, you can use https://try.kotlinlang.org/#/Kotlin%20Koans/Introduction/Java%20to%20Kotlin%20conversion/Task.kt.
I asked a question at How to design a complex class which incude some classes to make expansion easily in future in Kotlin? about how to design a complex class which incude some classes to make expansion easily in future in Kotlin.
A expert named s1m0nw1 give me a great answer as the following code.
But I don't know why he want to change MutableList to List at https://stackoverflow.com/posts/47960036/revisions , I can get the correct result when I use MutableList. Could you tell me?
The code
interface DeviceDef
data class BluetoothDef(val Status: Boolean = false) : DeviceDef
data class WiFiDef(val Name: String, val Status: Boolean = false) : DeviceDef
data class ScreenDef(val Name: String, val size: Long) : DeviceDef
class MDetail(val _id: Long, val devices: List<DeviceDef>) {
inline fun <reified T> getDevice(): T {
return devices.filterIsInstance(T::class.java).first()
}
}
Added
I think that mutableListOf<DeviceDef> is better than ListOf<DeviceDef> in order to extend in future.
I can use aMutableList.add() function to extend when I append new element of mutableListOf<DeviceDef>.
If I use ListOf<DeviceDef>, I have to construct it with listOf(mBluetoothDef1, mWiFiDef1, //mOther), it's not good. Right?
var aMutableList= mutableListOf<DeviceDef>()
var mBluetoothDef1= BluetoothDef(true)
var mWiFiDef1= WiFiHelper(this).getWiFiDefFromSystem()
aMutableList.add(mBluetoothDef1)
aMutableList.add(mWiFiDef1)
// aMutableList.add(mOther) //This is extension
var aMDetail1= MDetail(myID, aMutableList)
Sorry for not giving an explanation in the first place. The differences are explained in the docs.:
Unlike many languages, Kotlin distinguishes between mutable and immutable collections (lists, sets, maps, etc). Precise control over exactly when collections can be edited is useful for eliminating bugs, and for designing good APIs.
It is important to understand up front the difference between a read-only view of a mutable collection, and an actually immutable collection. Both are easy to create, but the type system doesn't express the difference, so keeping track of that (if it's relevant) is up to you.
The Kotlin List<out T> type is an interface that provides read-only operations like size, get and so on. Like in Java, it inherits from Collection<T> and that in turn inherits from Iterable<T>. Methods that change the list are added by the MutableList<T> interface. [...]
The List interface provides a read-only view so that you cannot e.g add new elements to the list which has many advantages for instance in multithreaded environments. There may be situations in which you will use MutableList instead.
I also recommend the following discussion:
Kotlin and Immutable Collections?
EDIT (added content):
You can do this is a one-liner without any add invocation:
val list = listOf(mBluetoothDef1, mWiFiDef1)
So I'm new to Scala (and have almost zero java experience). I thought I understood OOP, in abstract, but disregard that. My question -- in a similar vein to "method name qualification when using a companion object" -- is about when a Scala pro would think to implement a class - companion object pattern?
From the question referenced above, it's not clear that companion objects were intended to store methods for the class's "internal use" (e.g. the poster wanted to use ^, defined in the object, inside /, defined in the class). So, I don't want to think of companion objects as "containers" for methods the companion class can use, because that's clearly not true...
I'm sorry if this is a vague question: I just want to know the correct way to use these guys.
Companion objects are useful for what you would use static methods for in Java...
One very common use is to define an apply() method in the companion object, which gives users the ability to use MyObject(arg, arg) as shorthand for new MyObject(arg, arg).
Companion objects are also a good place to put things like implicit defs.
I recently have been using companion objects in my akka apps as places to put message case classes which are specific to a supervisor actor and its children, but that I don't necessarily want code outside that subsystem to use directly.
Here's a simple example:
class Complex(real:Double, imag:Double) {
def +(that:Complex):Complex = Complex(this.real + that.real, this.imag + that.imag)
// other useful methods
}
// the companion object
object Complex {
def apply(real:Double, imag:Double) = new Complex(real, imag)
val i = Complex(0, 1)
implicit def fromInt(i:Int) = Complex(i, 0)
}
The normal OOP way to instantiate a new Complex object would be new Complex(x, i). In my companion object, I defined the function apply, to give us a syntactic sugar that allows us to write Complex(x, i). apply is a special function name which is invoked whenever you call an object directly as if it were a function (i.e., Complex()).
I also have a value called i which evaluates to Complex(0, 1), which gives me a shorthand for using the common complex number i.
This could be accomplished in Java using a static method like:
public static Complex i() {
return new Complex(0, 1);
}
The companion object essentially gives you a namespace attached to your class name which is not specific to a particular instance of your class.