面试题答案
一键面试委托构造函数适用场景及举例
- 代码复用场景
- 场景阐述:当多个构造函数需要执行一些共同的初始化逻辑时,使用委托构造函数可以避免代码重复。例如,在创建一个表示用户的类时,无论通过何种方式创建用户对象,都可能需要初始化一些基本属性,如用户名和用户ID。
- 代码示例:
class User {
var userId: Int
var username: String
constructor(userId: Int, username: String) {
this.userId = userId
this.username = username
}
constructor(userInfo: Map<String, Any>) : this(
userInfo["userId"] as Int,
userInfo["username"] as String
)
}
在上述代码中,第二个构造函数通过委托第一个构造函数,复用了初始化userId
和username
的逻辑。这样,如果初始化逻辑发生变化,只需在一个地方修改即可。
- 简化复杂构造逻辑场景
- 场景阐述:当类的构造逻辑较为复杂,存在多种构造方式时,委托构造函数可以将复杂的构造逻辑分解为多个步骤,使得代码结构更清晰。比如创建一个图形类,不同的图形创建方式可能基于不同的参数组合,但都需要一些基础的图形属性初始化。
- 代码示例:
abstract class Shape {
var x: Int
var y: Int
constructor(x: Int, y: Int) {
this.x = x
this.y = y
}
constructor(point: Pair<Int, Int>) : this(point.first, point.second)
}
class Rectangle(x: Int, y: Int, var width: Int, var height: Int) : Shape(x, y) {
constructor(point: Pair<Int, Int>, width: Int, height: Int) : this(point.first, point.second, width, height)
}
这里Rectangle
类的第二个构造函数委托第一个构造函数,简化了创建Rectangle
对象时的构造逻辑,并且将基础的坐标初始化逻辑委托给了Shape
类的构造函数。
默认参数适用场景及举例
- 可选参数场景
- 场景阐述:当某个参数在大多数情况下有一个合理的默认值,只有在特殊情况下才需要用户指定不同的值时,适合使用默认参数。例如,在创建一个日志记录器类时,日志级别在大多数情况下可能是
INFO
,只有在调试或特殊需求时才会更改。 - 代码示例:
- 场景阐述:当某个参数在大多数情况下有一个合理的默认值,只有在特殊情况下才需要用户指定不同的值时,适合使用默认参数。例如,在创建一个日志记录器类时,日志级别在大多数情况下可能是
enum class LogLevel {
INFO, DEBUG, ERROR
}
class Logger {
fun log(message: String, level: LogLevel = LogLevel.INFO) {
println("$level: $message")
}
}
在上述代码中,log
函数的level
参数有默认值LogLevel.INFO
。用户调用log
函数时,如果不指定level
,就会使用默认的日志级别。
2. 向后兼容场景
- 场景阐述:在对已有函数进行功能扩展时,为了不影响现有的调用代码,可以通过添加带默认参数的新参数来实现。例如,有一个已有的计算两个数之和的函数,现在需要增加一个是否打印结果的功能。
- 代码示例:
fun add(a: Int, b: Int, printResult: Boolean = false): Int {
val result = a + b
if (printResult) {
println("The result is $result")
}
return result
}
原来调用add
函数的代码无需修改,而新的需求可以通过设置printResult
为true
来满足,实现了向后兼容。