Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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
Oop 为什么以及何时应该使用类型转换?_Oop_Kotlin - Fatal编程技术网

Oop 为什么以及何时应该使用类型转换?

Oop 为什么以及何时应该使用类型转换?,oop,kotlin,Oop,Kotlin,嘿,我刚刚发现了关于类型转换的问题,但我不明白它背后的概念是什么?你为什么要用那样的东西。我试着举个例子来更好地理解它: interface Fuel { //Fuel.kt var usingFuel : Boolean var typeFuel : String fun printInfo(){ println("Using this Fuel type: $typeFuel") } } 而otherKeros

嘿,我刚刚发现了关于类型转换的问题,但我不明白它背后的概念是什么?你为什么要用那样的东西。我试着举个例子来更好地理解它:

interface Fuel { 
    //Fuel.kt
    var usingFuel : Boolean
    var typeFuel : String

    fun printInfo(){
        println("Using this Fuel type: $typeFuel")
    }
}
otherKerosin.printInfo()
的输出与
airplane.printInfo()
的输出类似,只是燃料类型不同。现在我为什么要这样做,而不是创建一架新飞机并更改fuelType变量呢?

这行

var otherKerosin : Fuel = airplane
不会创建某事物的新实例。它只是获得了对同一实例的一个新引用,但将其类型缩小到了Fuel接口。使用
otherKerosin
所做的任何更改也会更改指定给
飞机的原始飞机(反之亦然),因为这两个变量都指向同一实例

在您给出的示例中,没有理由这样做
其他煤油
不必要地将其类型限制为
燃油
,这隐藏了
飞机
可能具有的不属于
燃油
接口的额外功能。它为您提供了原始
飞机
参考所不能提供的一切。但是,如果您从一个函数返回飞机,而调用该函数的类只需要使用
燃料
,那么您可能只需要返回
燃料
,这样您就不会向外界暴露太多。例如:

interface FuelProvider {
    fun provideFuel(): Fuel
}

class AirplaneProvider: FuelProvider {
    override fun provideFuel(): Fuel = Airplane() // Airplane is cast to Fuel
}
class FuelStorage(var fuel: Fuel? = null)

val storage = FuelStorage()
val airplane = Airplane()
storage.fuel = airplane // the Airplane is cast to Fuel to put it in the `fuel` property.
几乎不需要强制转换到更窄类型的局部变量。但有时,您的成员属性的类型比手头的对象窄,并且仍然希望将其指定给该属性。例如:

interface FuelProvider {
    fun provideFuel(): Fuel
}

class AirplaneProvider: FuelProvider {
    override fun provideFuel(): Fuel = Airplane() // Airplane is cast to Fuel
}
class FuelStorage(var fuel: Fuel? = null)

val storage = FuelStorage()
val airplane = Airplane()
storage.fuel = airplane // the Airplane is cast to Fuel to put it in the `fuel` property.
这里的
FuelStorage
类不关心它的
燃料是飞机还是其他类型的
燃料

我可以举一个例子,你可能想这样做,那就是如果你正在编写一个长函数,你想用一个变量来限制你的能力,使可用的操作更简单。在一个很长的函数中,这可以帮助您跟踪您正在做的事情。但是,如果一个函数变得足够长,以致于它实际上是有用的,那么它可能是一种代码味道

请注意,您所问的和我在上面讨论过的转换类型是隐式转换,它是通过将某些内容分配给实例匹配的属性或变量,或者通过从返回类型为匹配的函数返回某些内容来自动完成的

您还可以使用
as
as?
显式强制转换,这是在您要强制转换到的类型与您要强制转换的类型不匹配时执行的。例如,如果您有一个
燃料
,并且希望将其投射到
飞机
Fuel
并不总是
飞机
,因此必须显式强制转换以更改参考类型。如果基础实例实际上不是
飞机
,则此操作将失败,除非您使用safe cast
作为

您还可以通过使用
if
检查来检查局部变量是否属于某一类型或是否为null来进行智能强制转换。检查后,编译器可以假设变量引用的是已检查的类型。

此行

var otherKerosin : Fuel = airplane
不会创建某事物的新实例。它只是获得了对同一实例的一个新引用,但将其类型缩小到了Fuel接口。使用
otherKerosin
所做的任何更改也会更改指定给
飞机的原始飞机(反之亦然),因为这两个变量都指向同一实例

在您给出的示例中,没有理由这样做
其他煤油
不必要地将其类型限制为
燃油
,这隐藏了
飞机
可能具有的不属于
燃油
接口的额外功能。它为您提供了原始
飞机
参考所不能提供的一切。但是,如果您从一个函数返回飞机,而调用该函数的类只需要使用
燃料
,那么您可能只需要返回
燃料
,这样您就不会向外界暴露太多。例如:

interface FuelProvider {
    fun provideFuel(): Fuel
}

class AirplaneProvider: FuelProvider {
    override fun provideFuel(): Fuel = Airplane() // Airplane is cast to Fuel
}
class FuelStorage(var fuel: Fuel? = null)

val storage = FuelStorage()
val airplane = Airplane()
storage.fuel = airplane // the Airplane is cast to Fuel to put it in the `fuel` property.
几乎不需要强制转换到更窄类型的局部变量。但有时,您的成员属性的类型比手头的对象窄,并且仍然希望将其指定给该属性。例如:

interface FuelProvider {
    fun provideFuel(): Fuel
}

class AirplaneProvider: FuelProvider {
    override fun provideFuel(): Fuel = Airplane() // Airplane is cast to Fuel
}
class FuelStorage(var fuel: Fuel? = null)

val storage = FuelStorage()
val airplane = Airplane()
storage.fuel = airplane // the Airplane is cast to Fuel to put it in the `fuel` property.
这里的
FuelStorage
类不关心它的
燃料是飞机还是其他类型的
燃料

我可以举一个例子,你可能想这样做,那就是如果你正在编写一个长函数,你想用一个变量来限制你的能力,使可用的操作更简单。在一个很长的函数中,这可以帮助您跟踪您正在做的事情。但是,如果一个函数变得足够长,以致于它实际上是有用的,那么它可能是一种代码味道

请注意,您所问的和我在上面讨论过的转换类型是隐式转换,它是通过将某些内容分配给实例匹配的属性或变量,或者通过从返回类型为匹配的函数返回某些内容来自动完成的

您还可以使用
as
as?
显式强制转换,这是在您要强制转换到的类型与您要强制转换的类型不匹配时执行的。例如,如果您有一个
燃料
,并且希望将其投射到
飞机
Fuel
并不总是
飞机
,因此必须显式强制转换以更改参考类型。如果基础实例实际上不是
飞机
,则此操作将失败,除非您使用safe cast
作为

您还可以通过检查