🎬 HoRain 云小助手:个人主页
⛺️生活的理想,就是为了理想的生活!
⛳️ 推荐
前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。
目录
⛳️ 推荐
Kotlin 接口
1. 接口基本语法
1.1 定义接口
1.2 实现接口
2. 接口属性
2.1 抽象属性
2.2 带访问器的属性
3. 接口中的默认方法实现
4. 函数式接口(SAM 接口)
5. 接口继承
6. 接口与抽象类比较
7. 实际应用示例
7.1 策略模式
7.2 观察者模式
7.3 仓库模式
8. 接口委托
9. 内联接口(Kotlin 1.5+)
10. 标记接口
11. 最佳实践
11.1 接口设计原则
11.2 接口 vs 抽象类选择
11.3 工厂模式示例
总结
Kotlin 接口
接口是 Kotlin 中实现多态和抽象的重要机制,它定义了一组契约,类可以通过实现接口来遵循这些契约。
1. 接口基本语法
1.1 定义接口
// 简单接口 interface MyInterface { fun foo() fun bar() } // 带属性的接口 interface Named { val name: String } // 带默认实现的接口 interface Speaker { fun speak() { println("Speaking...") } }1.2 实现接口
// 单一接口实现 class SimpleClass : MyInterface { override fun foo() { println("foo") } override fun bar() { println("bar") } } // 多个接口实现 class MultiInterfaceClass : MyInterface, Named, Speaker { override val name: String = "MultiClass" override fun foo() { println("foo in MultiInterfaceClass") } override fun bar() { println("bar in MultiInterfaceClass") } }2. 接口属性
2.1 抽象属性
interface User { val email: String val nickname: String get() = email.substringBefore('@') } class PrivateUser(override val email: String) : User class SubscribingUser(val emailAddress: String) : User { override val email: String get() = emailAddress } // 使用 val privateUser = PrivateUser("alice@example.com") println(privateUser.email) // alice@example.com println(privateUser.nickname) // alice val subscribingUser = SubscribingUser("bob@example.com") println(subscribingUser.email) // bob@example.com println(subscribingUser.nickname) // bob2.2 带访问器的属性
interface Person { val name: String val age: Int val description: String get() = "$name is $age years old" val isAdult: Boolean get() = age >= 18 } class Student(override val name: String, override val age: Int) : Person fun main() { val student = Student("Alice", 20) println(student.description) // Alice is 20 years old println(student.isAdult) // true }3. 接口中的默认方法实现
interface Clickable { fun click() // 抽象方法 fun showOff() = println("I'm clickable!") // 带默认实现 } interface Focusable { fun setFocus(focused: Boolean) = println("I ${if (focused) "got" else "lost"} focus.") fun showOff() = println("I'm focusable!") } class Button : Clickable, Focusable { override fun click() = println("Button clicked") // 必须重写冲突的默认方法 override fun showOff() { super<Clickable>.showOff() super<Focusable>.showOff() } } fun main() { val button = Button() button.click() // Button clicked button.setFocus(true) // I got focus. button.showOff() // I'm clickable! // I'm focusable! }4. 函数式接口(SAM 接口)
只有一个抽象方法的接口称为函数式接口(SAM - Single Abstract Method)。
// 使用 fun interface 声明函数式接口 fun interface IntPredicate { fun accept(i: Int): Boolean } // 传统方式实现 val isEven = object : IntPredicate { override fun accept(i: Int): Boolean = i % 2 == 0 } // 使用 lambda 表达式 val isEvenLambda: IntPredicate = { it % 2 == 0 } // 使用函数引用 fun isEvenMethod(i: Int): Boolean = i % 2 == 0 val isEvenRef: IntPredicate = ::isEvenMethod fun main() { println(isEven.accept(4)) // true println(isEvenLambda.accept(4)) // true println(isEvenRef.accept(4)) // true }5. 接口继承
interface Base { fun print() } interface Derived : Base { fun printDerived() } class MyClass : Derived { override fun print() { println("Base implementation") } override fun printDerived() { println("Derived implementation") } } // 接口多继承 interface A { fun foo() { println("A") } } interface B { fun foo() { println("B") } fun bar() { println("bar") } } interface C : A, B { override fun foo() { super<A>.foo() super<B>.foo() println("C") } } class D : C { override fun bar() { println("D bar") } } fun main() { val d = D() d.foo() // A // B // C d.bar() // D bar }6. 接口与抽象类比较
特性 | 接口 | 抽象类 |
|---|---|---|
多重继承 | ✓ 一个类可实现多个接口 | ✗ 只能继承一个抽象类 |
状态 | ✗ 不能有状态(属性不能初始化) | ✓ 可以有状态(属性可初始化) |
构造函数 | ✗ 没有构造函数 | ✓ 可以有主/次构造函数 |
默认实现 | ✓ 可以有方法默认实现 | ✓ 可以有方法实现 |
属性访问器 | ✓ 可以有属性访问器 | ✓ 可以有属性访问器 |
初始化块 | ✗ 不能有 init 块 | ✓ 可以有 init 块 |
7. 实际应用示例
7.1 策略模式
interface PaymentStrategy { fun pay(amount: Double) } class CreditCardPayment : PaymentStrategy { override fun pay(amount: Double) { println("Paying $$amount with Credit Card") } } class PayPalPayment : PaymentStrategy { override fun pay(amount: Double) { println("Paying $$amount with PayPal") } } class ShoppingCart(private var strategy: PaymentStrategy) { fun setPaymentStrategy(strategy: PaymentStrategy) { this.strategy = strategy } fun checkout(amount: Double) { strategy.pay(amount) } } fun main() { val cart = ShoppingCart(CreditCardPayment()) cart.checkout(100.0) // Paying $100.0 with Credit Card cart.setPaymentStrategy(PayPalPayment()) cart.checkout(200.0) // Paying $200.0 with PayPal }7.2 观察者模式
interface Observer { fun update(message: String) } interface Observable { fun addObserver(observer: Observer) fun removeObserver(observer: Observer) fun notifyObservers(message: String) } class NewsAgency : Observable { private val observers = mutableListOf<Observer>() override fun addObserver(observer: Observer) { observers.add(observer) } override fun removeObserver(observer: Observer) { observers.remove(observer) } override fun notifyObservers(message: String) { observers.forEach { it.update(message) } } fun publishNews(news: String) { println("News published: $news") notifyObservers(news) } } class NewsChannel(val name: String) : Observer { override fun update(message: String) { println("$name received: $message") } } fun main() { val agency = NewsAgency() val channel1 = NewsChannel("CNN") val channel2 = NewsChannel("BBC") agency.addObserver(channel1) agency.addObserver(channel2) agency.publishNews("Kotlin 1.9 released!") // 输出: // News published: Kotlin 1.9 released! // CNN received: Kotlin 1.9 released! // BBC received: Kotlin 1.9 released! }7.3 仓库模式
interface Repository<T> { fun getById(id: Int): T? fun getAll(): List<T> fun save(item: T) fun delete(id: Int) } class User(val id: Int, val name: String) class UserRepository : Repository<User> { private val users = mutableMapOf<Int, User>() override fun getById(id: Int): User? { return users[id] } override fun getAll(): List<User> { return users.values.toList() } override fun save(item: User) { users[item.id] = item } override fun delete(id: Int) { users.remove(id) } }8. 接口委托
Kotlin 支持通过委托实现接口,这是实现装饰器模式的强大工具。
interface Printer { fun printDocument(document: String) } class LaserPrinter : Printer { override fun printDocument(document: String) { println("Laser printing: $document") } } // 通过委托实现接口 class LoggingPrinter(private val printer: Printer) : Printer by printer { override fun printDocument(document: String) { println("Log: Printing document") printer.printDocument(document) println("Log: Document printed") } } fun main() { val printer = LaserPrinter() val loggingPrinter = LoggingPrinter(printer) loggingPrinter.printDocument("Report.pdf") // 输出: // Log: Printing document // Laser printing: Report.pdf // Log: Document printed }9. 内联接口(Kotlin 1.5+)
// 内联类实现接口 interface Printable { fun print(): String } @JvmInline value class Name(val s: String) : Printable { override fun print(): String = "Name: $s" } fun main() { val name = Name("Kotlin") println(name.print()) // Name: Kotlin }10. 标记接口
标记接口是没有任何方法或属性的接口,用于标记类型。
// 标记接口 interface Entity interface Service interface Repository // 使用 class User : Entity class UserService : Service class UserRepository : Repository // 类型检查 fun process(entity: Entity) { when (entity) { is User -> println("Processing user") // 处理其他 Entity } }11. 最佳实践
11.1 接口设计原则
// 1. 接口分离原则 - 多个小接口优于一个大接口 interface Readable { fun read(): String } interface Writable { fun write(data: String) } interface Deletable { fun delete() } // 2. 明确命名 interface UserAuthenticator // 好 interface Auth // 不够明确 // 3. 使用默认实现减少重复代码 interface JsonSerializable { fun toJson(): String fun isValidJson(): Boolean { return try { // JSON 验证逻辑 true } catch (e: Exception) { false } } }11.2 接口 vs 抽象类选择
// 使用接口的场景 interface Vehicle { val maxSpeed: Int fun start() fun stop() } // 使用抽象类的场景 abstract class Animal { abstract val name: String val isAlive: Boolean = true // 可以有状态 abstract fun makeSound() open fun sleep() { // 可以有非 final 方法 println("$name is sleeping") } init { // 可以有初始化块 println("Animal created") } }11.3 工厂模式示例
interface Shape { fun draw() fun area(): Double } class Circle(val radius: Double) : Shape { override fun draw() = println("Drawing circle with radius $radius") override fun area() = Math.PI * radius * radius } class Rectangle(val width: Double, val height: Double) : Shape { override fun draw() = println("Drawing rectangle ${width}x$height") override fun area() = width * height } object ShapeFactory { fun createShape(type: String, vararg params: Double): Shape? { return when (type.lowercase()) { "circle" -> if (params.size >= 1) Circle(params[0]) else null "rectangle" -> if (params.size >= 2) Rectangle(params[0], params[1]) else null else -> null } } } fun main() { val circle = ShapeFactory.createShape("circle", 5.0) val rectangle = ShapeFactory.createShape("rectangle", 4.0, 6.0) circle?.draw() // Drawing circle with radius 5.0 println(circle?.area()) // 78.53981633974483 rectangle?.draw() // Drawing rectangle 4.0x6.0 println(rectangle?.area()) // 24.0 }总结
Kotlin 接口是强大的抽象工具,具有以下特点:
支持默认实现:减少重复代码
多重继承:一个类可以实现多个接口
属性支持:可以定义抽象属性和带访问器的属性
函数式接口:支持 SAM 转换,可以使用 lambda
接口委托:通过委托模式实现代码复用
接口继承:接口可以继承其他接口
通过合理使用接口,可以创建灵活、可扩展、可维护的代码结构,是 Kotlin 面向对象编程的核心特性之一。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙