Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在kotlin中创建随机类的对象_Kotlin_Reflection_Polymorphism - Fatal编程技术网

在kotlin中创建随机类的对象

在kotlin中创建随机类的对象,kotlin,reflection,polymorphism,Kotlin,Reflection,Polymorphism,我在高中时学习了java和python,我对python非常熟悉。我最近开始学习kotlin,主要是为了好玩(定义函数的关键字是fun,所以它必须是一种有趣的语言,对吧),但我有一个小问题 假设我有一个棋子类的层次结构: 抽象类片段{ ... } 类车:件(){ ... } 班主教:件(){ ... } . . . 我从用户那里获取输入以生成板,因此如果用户键入r,我需要创建Rook对象,如果他键入b,我需要创建Bishop等 在python中,我可能会使用字典将输入字符串映射到相应的类,以便

我在高中时学习了java和python,我对python非常熟悉。我最近开始学习kotlin,主要是为了好玩(定义函数的关键字是
fun
,所以它必须是一种有趣的语言,对吧),但我有一个小问题

假设我有一个棋子类的层次结构:

抽象类片段{
...
}
类车:件(){
...
}
班主教:件(){
...
}
.
.
.
我从用户那里获取输入以生成板,因此如果用户键入
r
,我需要创建
Rook
对象,如果他键入
b
,我需要创建
Bishop

在python中,我可能会使用字典将输入字符串映射到相应的,以便创建正确类型的对象:

类块:
...
等级车(件):
...
班主教(件):
...
.
.
.
输入映射={
“r”:车,
b:主教,
...
}
s=input_映射[input()()#使用用户输入作为键并创建正确类型的块
当我发现这种模式时,我真的很惊讶。在java中,我必须使用一个switch case或一组
if-else if
来实现相同的结果,这并不是世界末日,特别是如果我将其抽象为一个单独的函数,但它不如python方法好

我想在kotlin中做同样的事情,我想知道kotlin是否有类似的模式,因为它是一种类似python的现代语言(我知道,我知道,python不是新语言,但我认为它非常现代)。我试图在线查看,但似乎无法像python中那样将类(类,而不是对象)存储在变量或映射中

我错了吗?我可以在kotlin中使用类似的模式吗?还是必须回到
when
语句(或表达式)

如果我没有弄错的话,可以使用反射在java中实现类似的模式。我从未深入学习过java中的反射,但我知道这是一种动态使用类的方法,我可以在python中免费使用。我还听说在java中,反射应该作为最后手段使用,因为它效率低下,如果你理解我的意思,它被认为是“黑魔法”。这是否意味着我需要在kotlin中使用反射来实现这一结果?如果是这样,是否建议在kotlin中使用反射,它是否有效


我想知道如何解决这个问题,我接受多个答案和我没有想到的其他解决方案。提前感谢。

是的,您可以使用与Kotlin类似的方法。Kotlin具有许多特性并支持反射。让我就你的问题写一个例子

首先创建将由用户输入生成的类

abstract class Piece

class Rook : Piece()
class Bishop : Piece()
创建类映射

val inputMap = mapOf(
        "r" to Rook::class.java,
        "b" to Bishop::class.java
)
使用
newInstance
函数创建所需的实例。如果您的输入映射不包含您提供的密钥,那么它将返回
null

    val rook = inputMap["r"]?.newInstance()
    val bishop = inputMap["b"]?.newInstance()
    
    // null
    val king = inputMap["k"]?.newInstance()
您还可以编写自定义扩展来创建新对象

    fun <T> Map<String, Class<out T>>.newInstance(key: String) = this[key]?.newInstance()

    // Create an instance with extension function
    inputMap.newInstance("r")
fun Map.newInstance(key:String)=这个[key]?.newInstance()
//使用扩展函数创建实例
inputMap.newInstance(“r”)

是的,您可以对Kotlin使用类似的方法。Kotlin具有许多特性并支持反射。让我就你的问题写一个例子

首先创建将由用户输入生成的类

abstract class Piece

class Rook : Piece()
class Bishop : Piece()
创建类映射

val inputMap = mapOf(
        "r" to Rook::class.java,
        "b" to Bishop::class.java
)
使用
newInstance
函数创建所需的实例。如果您的输入映射不包含您提供的密钥,那么它将返回
null

    val rook = inputMap["r"]?.newInstance()
    val bishop = inputMap["b"]?.newInstance()
    
    // null
    val king = inputMap["k"]?.newInstance()
您还可以编写自定义扩展来创建新对象

    fun <T> Map<String, Class<out T>>.newInstance(key: String) = this[key]?.newInstance()

    // Create an instance with extension function
    inputMap.newInstance("r")
fun Map.newInstance(key:String)=这个[key]?.newInstance()
//使用扩展函数创建实例
inputMap.newInstance(“r”)

这可以在没有反射的情况下完成

您可以将输入字符映射到构造函数:

val pieceConstructorsByKeyChar = mapOf(
    'r' to ::Rook,
    'b' to ::Bishop,
    // etc.
)
从映射中获取值会给您一个可为null的值,因为您提供的键可能不在映射中。也许这是好的,如果你在使用它的时候,你可能传递了一个玩家输入的可能不受支持的角色。然后你可能会告诉玩家再试一次来处理
null

val piece: Piece? = pieceConstructorsByKeyChar[keyPressed]?.invoke()
或者,如果您在检查是否为有效的按键笔划后进行查找,则可以使用
安全:

val piece: Piece = pieceConstructorsByKeyChar[keyPressed]!!()

这可以不经思考就完成

您可以将输入字符映射到构造函数:

val pieceConstructorsByKeyChar = mapOf(
    'r' to ::Rook,
    'b' to ::Bishop,
    // etc.
)
从映射中获取值会给您一个可为null的值,因为您提供的键可能不在映射中。也许这是好的,如果你在使用它的时候,你可能传递了一个玩家输入的可能不受支持的角色。然后你可能会告诉玩家再试一次来处理
null

val piece: Piece? = pieceConstructorsByKeyChar[keyPressed]?.invoke()
或者,如果您在检查是否为有效的按键笔划后进行查找,则可以使用
安全:

val piece: Piece = pieceConstructorsByKeyChar[keyPressed]!!()

酷。我是科特林的新手。在python中,这是一个python解决方案。你认为科特林的这个解决办法很好吗?我听说人们通常不喜欢java中的反射,我不知道它是否适用于kotlin。另外,如果我没有弄错的话,您的解决方案是针对kotlin for jvm的。这是最好的选择,还是有更通用的解决方案?我认为这取决于您的体系结构以及您想要什么。Kotlin可以完美地与Java一起工作,因此可以使用Java反射API,也可以提供自己的反射API。这两种方法都能完美地工作,没有任何问题。@ShaiAvr这些都是非常明智的问题!  正如你所说,在一种语言中什么是好的实践在另一种语言中可能不是这样,而且可能有更多的惯用替代方法。  我看到了很多关于使用动态语言的人提出的关于反射的问题,而非反射的解决方案通常更健壮、高效、安全、广泛支持和/或简洁。  这个答案清晰、详细,并且很好地解释了