鉴于以下三个kotlin类:
abstract class UseCase<T> {
fun execute(action: Action<T>) {
}
}
class ConcreteUseCase : UseCase<List<String>>()
class Action<T>
Run Code Online (Sandbox Code Playgroud)
我无法在java代码中编译以下行:
ConcreteUseCase s = new ConcreteUseCase();
s.execute(new Action<List<String>>());//<<<<<<< compilation error
Run Code Online (Sandbox Code Playgroud)
错误说:
SomeClass的<java.util.List的<?扩展Type >> in Class不能应用于SomeClass <java.util.List <Type >>
我仍然是kotlin的新手,这可能是一个非常小的东西,但我似乎无法弄明白.我将不胜感激任何帮助.
我在继承包含基类型的方法/乐趣的接口时遇到问题,我想将其重写为实现它的类中的子类型。
到目前为止我已经有了界面
interface IModel {
fun convert(dataModel: BaseDataModel)
}
Run Code Online (Sandbox Code Playgroud)
以及实现它的类:
class SettingsModel: IModel {
override fun convert(dataModel: BaseDataModel) {
// Conversion of models here
}
}
Run Code Online (Sandbox Code Playgroud)
我还有 SettingsDataModel 它是:
class SettingsDataModel: BaseDataModel() {
}
Run Code Online (Sandbox Code Playgroud)
我想要实现的是对于每个实现 IModel 的类/模型,能够获取特定的 DataModel,例如:
class SettingsModel: IModel {
override fun convert(dataModel: SettingsDataModel) {
// Conversion of models here
}
}
Run Code Online (Sandbox Code Playgroud)
无需投射它。我想我不能,因为它修改了乐趣的签名,使其不是真正的覆盖。我尝试使用泛型和泛型约束,但没有运气:
interface IModel {
fun <T :BaseDataModel>convert(dataModel: T)
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用。有解决这个问题的方法吗?
我想向接口添加一个函数,该函数返回具体实现的对象。
因此,使用界面:
interface Content {
fun <???> cloneMe(): ?
}
Run Code Online (Sandbox Code Playgroud)
和班级
class Music: Content
class Video: Content
Run Code Online (Sandbox Code Playgroud)
该功能cloneMe()
的的Music
类应该返回一个Music
对象和函数cloneMe()
中的Video
类应返回一个Video
对象。
我最接近的是:
interface Content {
fun <T: Content> cloneMe(): T
}
class Music : Content {
override fun <T : Content> cloneMe(): T {
return Music() as T
}
}
Run Code Online (Sandbox Code Playgroud)
那我就可以
val music: Music = Music().cloneMe<Music>()
Run Code Online (Sandbox Code Playgroud)
这里的问题是我必须进行未经检查的强制转换,“允许我”(即可以编译)执行
class Music : Content {
override fun <T : Content> cloneMe(): T {
return …
Run Code Online (Sandbox Code Playgroud) 我试图让一个普通的可怜人的数据持久化功能,将采取一个MutableSet的数据类,并将其序列化到磁盘.我想要一些简单的原型设计,并且可以经常在集合上调用"save()",这样如果我的进程被杀死,我可以稍后使用已保存条目的"load()"恢复.
但即使重读了Generics页面,我也没有完全区分'*','in','out'和'Nothing'之间的区别.这个SEEMS可以在不抛出错误的情况下工作,但我不明白为什么他们都"出局",我认为一个人必须"进入"...或者更可能我理解Kotlin Generics完全错误.这样做有正确的方法吗?
/** Save/load any MutableSet<Serializable> */
fun MutableSet<out Serializable>.save(fileName:String="persist_${javaClass.simpleName}.ser") {
val tmpFile = File.createTempFile(fileName, ".tmp")
ObjectOutputStream(GZIPOutputStream(FileOutputStream(tmpFile))).use {
println("Persisting collection with ${this.size} entries.")
it.writeObject(this)
}
Files.move(Paths.get(tmpFile), Paths.get(fileName), StandardCopyOption.REPLACE_EXISTING)
}
fun MutableSet<out Serializable>.load(fileName:String="persist_${javaClass.simpleName}.ser") {
if (File(fileName).canRead()) {
ObjectInputStream(GZIPInputStream(FileInputStream(fileName))).use {
val loaded = it.readObject() as Collection<Nothing>
println("Loading collection with ${loaded.size} entries.")
this.addAll(loaded)
}
}
}
data class MyWhatever(val sourceFile: String, val frame: Int) : Serializable
Run Code Online (Sandbox Code Playgroud)
然后能够启动任何应用程序
val mySet = mutableSetOf<MyWhatever>()
mySet.load()
Run Code Online (Sandbox Code Playgroud) 假设我有以下代码:
open class Fruit
class Apple : Fruit()
open class Juice<T : Fruit>
class AppleJuice : Juice<Apple>()
fun <F : Fruit, J : Juice<F>> makeJuice(juiceClass : Class<J>, fruit : F) : J {}
Run Code Online (Sandbox Code Playgroud)
我这样调用该函数:
val appleJuice : AppleJuice = makeJuice(AppleJuice::class.java, Apple())
Run Code Online (Sandbox Code Playgroud)
但是,我不想传递类对象,而是希望将其AppleJuice
作为类型传递:
val appleJuice : AppleJuice = makeJuice<AppleJuice>(Apple())
Run Code Online (Sandbox Code Playgroud)
我重构了我的功能以内联reified
:
inline fun <F : Fruit, reified J : Juice<F>> makeJuice(fruit : F) : J {}
Run Code Online (Sandbox Code Playgroud)
但是现在我必须指定两种类型:
val appleJuice : AppleJuice = makeJuice<Apple, AppleJuice>(Apple())
Run Code Online (Sandbox Code Playgroud)
从理论上讲,Apple
不需要类型,因为它已经从AppleJuice …
我有以下课程:
abstract class PresenterActivity<S : ViewState, I : ViewIntent> : AppCompatActivity() {
open fun initViewIntent(): I {
return object : ViewIntent{} // type mismatch on this line
}
}
Run Code Online (Sandbox Code Playgroud)
我收到一个预编译错误,说明:
Type mismatch
Required: I
Found: <S, I>
Run Code Online (Sandbox Code Playgroud)
为了解决这个预编译错误,我将ViewIntent对象转换为I:
abstract class PresenterActivity<S : ViewState, I : ViewIntent> : AppCompatActivity() {
open fun initViewIntent(): I {
@Suppress("UNCHECKED_CAST")
return object : ViewIntent{} as I
}
}
Run Code Online (Sandbox Code Playgroud)
但为什么Kotlin不能检测到I
必须从中衍生出来ViewIntent
并且聪明地施展它?
val editText1 = findViewById<EditText>(R.id.editText1);
if(comNum != editText1.toString().toInt() ){
View4.text = "??"
} else View4.text = "??"
Run Code Online (Sandbox Code Playgroud)
安装 apk
无法正常工作.我认为edittext.toString.toInt
是错的.