kotlin之open class继承

7 kotlin之class继承open
open表示可继承,extends也被改为:
open class Car(brand: String) {
    var brand: String = brand
    fun showBrand() {
        println("This brand is $brand ")
    }
}

class Lexus : Car("Lexus") {}
class Honda : Car("Honda") {}

fun main() {
    var car = Car("Toyota")
    var lexus = Lexus()
    var honda = Honda()

    car.showBrand()
    lexus.showBrand()
    honda.showBrand()
}
 

喜欢可以加Q群号:874826112,一起学习,成长,交流工作经验,
记得要点赞,评论哦😯;

更多相关内容请点击主页查看,有你想不到的惊喜😂…

简书: https://www.jianshu.com/u/88db5f15770d

csdn:https://me.youkuaiyun.com/beyondforme

掘金:https://juejin.im/user/5e09a9e86fb9a016271294a7

<think>嗯,用户想了解Kotlinopen类和abstract类的区别。我需要先回忆一下Kotlin的相关知识。 首先,Kotlin默认情况下类都是final的,不能被继承,除非用open关键字修饰。这点和Java不同,Java的类默认是open的。所以open类的主要作用是允许其他类继承它,但open类本身可以包含具体的实现,也可以有抽象成员吗?或者说抽象类必须包含抽象成员? 然后,抽象类abstract class,和Java中的类似,必须被继承才能实例化。抽象类可以包含抽象方法和具体方法。而抽象方法必须在子类中实现。另外,抽象类本身不能创建实例,这一点和open类不同,open类如果没有抽象成员的话可以直接实例化。 那两者的区别可能在于:open类需要显式标记为open才能被继承,而抽象类本身就是必须被继承的。同时,抽象类可以有抽象成员,而open类如果要有抽象成员的话,是否需要将成员也标记为abstract呢?比如,在open类中,如果要让某个方法被子类重写,是否需要同时用open和abstract?或者abstract只能在抽象类中使用? 可能的情况是,在抽象类中,抽象成员必须没有实现,且子类必须重写。而open类中的方法如果要被重写,需要显式标记为open,然后在子类中用override。但open类中的方法如果没有被标记为open,子类无法重写。而抽象类中的抽象方法不需要open关键字,因为已经隐式是open的,需要子类实现。 另外,构造函数的处理可能也有不同。抽象类可以有主构造函数和次构造函数,而open类同样可以有,但抽象类不能直接实例化。 可能还需要提到,抽象类的存在是为了定义一些基础结构,要求子类必须实现某些方法,而open类更多是允许继承,但不强制要求重写方法,除非方法被标记为open,并且子类选择去重写。 总结的话,区别应该包括:默认的成员是否可重写、是否需要强制实现、能否直接实例化、使用场景的不同。比如,抽象类用于需要子类必须实现某些方法的场景,而open类用于允许继承但不需要强制重写的场景。 需要确认一下,Kotlinopen类是否可以包含抽象成员?或者只有抽象类才能有抽象成员?根据Kotlin的语法,只有抽象类才能声明抽象成员,open类中的方法如果需要子类重写,必须显式标记为open,但如果没有实现的话,可能不行,必须用abstract。所以可能open类中的抽象成员必须同时用abstract修饰,但这样的话该类必须声明为abstract类。因此,open类不能有抽象成员,只有抽象类可以。这可能是一个关键区别。 比如,在Kotlin中: open class OpenClass { open fun someMethod() { ... } // 可以被重写 // abstract fun anotherMethod() // 错误,不能在open类中声明抽象方法,必须使用abstract class } abstract class AbstractClass { abstract fun mustImplement() fun concreteMethod() { ... } } 所以,区别之一是抽象类可以有抽象成员,而open类不能,除非该类本身是抽象的。也就是说,如果一个类有抽象成员,它必须声明为abstract,而不能仅仅是open。 因此,主要的区别点应该是: 1. 继承性:open类需要显式标记才能被继承,而抽象类本身必须被继承。 2. 抽象成员:抽象类可以有抽象成员(必须被子类实现),而open类不能有抽象成员。 3. 实例化:抽象类不能被实例化,open类可以(如果没有抽象成员)。 4. 方法重写:在open类中,方法需要标记为open才能被重写;在抽象类中,抽象方法必须被重写,非抽象方法如果需要被重写,可能需要标记为open(如果抽象类中的方法默认是final的吗?) 比如,在抽象类中的非抽象方法默认是final的,除非标记为open。例如: abstract class MyAbstract { abstract fun mustOverride() fun cannotOverride() { ... } // 子类不能重写 open fun canOverride() { ... } // 子类可以重写 } 所以,在抽象类中的具体方法默认是不能被重写的,除非用open修饰。而抽象方法隐式是open的,必须被重写。 而open类中的方法,如果要被重写,也需要显式标记open,子类用override。例如: open class MyOpen { open fun canOverride() { ... } fun cannotOverride() { ... } } 总结这些点,应该能回答用户的问题了。需要确保结构清晰,分点说明,同时给出示例代码,但用户可能需要用中文解释,所以示例可能需要用文字描述,或者在代码块中展示。 最后,可能还需要提到使用场景:当需要定义一个可继承的类,但不需要强制子类实现某些方法时,用open类;当需要定义部分未实现的模板,强制子类完成时,用抽象类。</think>Kotlin 中 `open class` 和 `abstract class` 的区别可通过以下对比逐步理解: --- ### **1. 核心设计目的** - **`open class`** 用于定义**可被继承的基类**,但本身是“完整实现”的。Kotlin 默认所有类为 `final`(不可继承),`open` 关键字显式打破这一限制。 - **`abstract class`** 用于定义**必须被继承的基类**,且包含**未实现的抽象成员**(抽象方法或属性)。抽象类本身是“不完整”的,无法直接实例化。 --- ### **2. 继承与实例化** - **`open class`** - **可被继承**:需显式标记 `open`。 - **可直接实例化**:若无抽象成员,可直接通过构造函数创建对象。 ```kotlin open class Animal(val name: String) { open fun makeSound() { println("默认叫声") } } // 实例化 open 类 val animal = Animal("普通动物") ``` - **`abstract class`** - **必须被继承**:无法直接实例化。 - **依赖子类实现**:子类必须实现所有抽象成员。 ```kotlin abstract class Shape { abstract fun area(): Double // 抽象方法,子类必须实现 fun printType() { println("这是一个形状") } // 具体方法 } class Circle(val radius: Double) : Shape() { override fun area() = Math.PI * radius * radius } ``` --- ### **3. 成员重写规则** - **`open class` 的成员** - 默认不可被重写。若需允许子类重写,需显式标记 `open`。 - 子类重写时需用 `override` 关键字。 ```kotlin open class Animal { open fun move() { println("移动") } // 允许重写 fun eat() { println("进食") } // 默认不可重写 } class Bird : Animal() { override fun move() { println("飞行") } // 无法重写 eat() } ``` - **`abstract class` 的成员** - 抽象成员(`abstract` 标记)必须被重写。 - 非抽象成员默认不可重写,除非显式标记 `open`。 ```kotlin abstract class Vehicle { abstract fun startEngine() // 必须被重写 open fun stopEngine() { println("引擎停止") } // 可重写 fun checkFuel() { println("燃料充足") } // 不可重写 } class Car : Vehicle() { override fun startEngine() { println("汽车启动") } override fun stopEngine() { println("自定义停止逻辑") } } ``` --- ### **4. 使用场景** - **`open class`** 适用于需要提供**默认实现**,但允许子类选择性扩展或修改的基类。例如:工具类、可配置的组件。 - **`abstract class`** 适用于定义**模板或规范**,强制子类实现特定逻辑。例如:定义算法骨架(模板方法模式)、接口的部分实现。 --- ### **总结对比表** | 特性 | `open class` | `abstract class` | |---------------------|-----------------------------|-----------------------------| | **能否直接实例化** | ✅(若无抽象成员) | ❌ | | **是否强制继承** | 否(显式继承) | 是(必须继承) | | **是否含抽象成员** | 否 | 是(至少一个) | | **成员默认可重写性**| 默认不可重写(需 `open`) | 抽象成员必须重写,非抽象成员默认不可重写(需 `open`) | --- 通过合理选择 `open` 和 `abstract`,可以更精确地控制类的继承与扩展行为,提升代码的可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值