- // 这段代码定义了一个公开的、不可被继承的Test类
- class Test{
-
- }
- // 没有类体,可以省略花括号
- class Test
底层代码:class Test{} / class Test 底层编译成java代码 如下:
- // final: 这个关键字说明Test类是一个最终类,意味着它不能被继承。
- // 也就是说,不允许有其他类继承自Test类以扩展其功能。
- public final class Test {
- }
- class Foo{
- val x:Int = 1
- }
- // 下边定义类的主构造函数,且添加了2个Int类型的参数
- class Test constructor(a: Int, b: Int) {
- }
- // 也可以省略constructor关键字,如果主构造函数没有任何注解或可见性修饰符:
- class Test (a: Int, b: Int) {
- }
a 和 b 同时作为构造函数的参数和类的属性存在- // a和 b 都是类的属性
- class Test constructor(val a: Int, var b: Int) {
- }
- // 也可以给参数使用默认值:
- class Test constructor(val a: Int = 1, var b: Int = 2) {
- }
- // 或者在类里边定义属性
- class Test01 (a: Int, b: Int) {
- // 在类定义类属性,此时a和b作为参数传进来
- var c: Int = a // 定义类属性c
- var d: Int = b // 定义类属性d
- init {
- println("$c+$d=${c+d}")
- }
- }
-
- fun main() {
- Test01(1, 2)
- }
作为参数:
在构造函数定义中,a 和 b 接收从外界传入的具体值,允许在创建 Test01 类的实例时初始化这些值。
作为属性val a: Int 表明 a 是一个只读属性(final变量),一旦在构造函数中初始化后,其值就不能再改变。var b: Int 表明 b 是一个可变属性(变量),在类的实例创建后,其值仍然可以被修改。
1、参数传递,初始化类中变量。
2、使用定义的默认值,初始化类变量。
3、如果不想第一时间初始化变量,可以使用 lateinit 懒加载:
- class Test () {
- lateinit var a: String
- lateinit var b: String
- }
为什么Int类型不能使用lateinit 懒加载?
原因如下:
对于基本数据类型(如 Int、Double、Boolean 等),它们不能为 null,并且在声明时必须赋予一个初始值。由于基本类型不是引用类型,它们不存在“未初始化”的状态——它们要么有一个具体的值,要么在局部作用域内如果没有初始化就会导致编译错误。因此,lateinit 机制不适用于基本数据类型,因为基本类型总是有默认值(如 Int 的默认值是 0),且不能为 null。
- class Test (b:Int) {
- var a: Int = b
- // 为a变量定义getter,打印a变量时,输出2,getter优先级是最高的
- get() {
- return 2
- }
- set(value) {
- field = value
- }
- init {
- println(a) // 2
- }
- }
-
- fun main() {
- Test(1)
- }
- // 方法定义
- fun main() {
- // 引用Foo类中的x属性
- val r = Foo::x
- // 方式一:调用Foo类中的x属性,获取其值
- val r1 = r.get(Foo("hello"))
- println("r1 -> $r1") // r1 -> hello
- // 方式二:通过实例化的对象foo来引用Foo类中的x属性
- val foo = Foo("world")
- val r2 = foo::x
- println("r2 -> ${r2.get()}") // r2 -> world
- }
- class Foo(x:String) {
- val x:String = x
- }
- // 记住一点:所有的次构造函数必须要调用主构造函数。
- class Test (var name:String) {
- // 次构造函数的创建如下,
- // (1)在类里边添加constructor关键字
- // (2)通过this()来调用主构造函数 Test()
- // 且this()参数必须和主构造函数的参数一致
- constructor(name:String,age:Int): this(name){}
- }
1、在kotlin中实例化类后,会创建一个新的对象,并且返回对象的引用,在构造函数执行完毕后,会返回一个指向新创建对象的引用,这个引用可以被存储在一个变量中,以便后续使用。
- class Test (var name:String)
-
- fun main() {
- val user:Test =Test("小王")
- // 通过user变量可以访问类中的属性、函数
- println(user.name) // 小王
- }
2、类方法定义及调用
- class Test(name: String) {
- // 定义info方法,参数为String类型
- fun info(name: String) {
- // 就近原则:所以输出 2
- println("名字为:${name}") // 2
- }
- }
-
- fun main() {
- val test = Test("1")
- test.info("2")
- }
在方法中,如果想调用主构造函数参数,需要使用 this. 的方式,且主构造函数参数必须是属性。
- class Test(var name: String) {
- fun info(name: String) {
- // this 就是Test 实例化的对象
- println("名字为:${this.name}") // 1
- }
- }
-
- fun main() {
- val test = Test("1")
- test.info("2")
- }
1、定义
- // Foo类 实现 FooInterface接口
- class Foo(val x: String):FooInterface{
- // 重写接口中foo方法
- override fun foo() {
- TODO("Not yet implemented")
- }
- }
- // 定义接口
- interface FooInterface {
- // 定义接口中的方法
- fun foo()
- }
2、实现接口
接口的实现,需要在实现类后边加上 : ,后边写上接口类名即可
- // Foo类实现 FooInterface接口
- class Foo(val x: String):FooInterface{
- }
(1)接口的定义,不需要添加关键字 class。
(2)实现类继承某个接口,后边添加 : 然后填写接口名即可 class T( ): AInterface{ }
(3)重写接口中的方法,在实现类中 需要添加 关键字 override
1、定义
- // 定义抽象类
- abstract class FooAbstract {
- // 定义抽象类中的方法
- abstract fun foo()
- }
2、抽象类中,如果没定义abstract 关键字, 那么该方法默认是不可被重写的;如果需要重写,必须加上关键字 open :
- // 定义抽象类
- abstract class FooAbstract {
- // 定义抽象方法,可以被重写
- abstract fun gar()
- // 不可被重写的方法
- fun foo(){}
- // 可被重写的方法
- open fun bar(){}
- }
3、类实现抽象类,重写里边的方法:
- // Foo类 实现 FooAbstract抽象类
- class Foo(val x: String):FooAbstract(){
- // 重写接口中foo方法
- override fun bar() {
- println("Foo:$x")
- }
- override fun gar() {
- println("Foo:$x")
- }
- }
- // 定义抽象类
- abstract class FooAbstract {
- // 定义抽象方法,可以被重写
- abstract fun gar()
- // 不可被重写的方法
- fun foo(){}
- // 可被重写的方法
- open fun bar(){}
- }
(1)定义抽象类,前边加上 abstract 关键字。
(2)抽象类中的方法(注意不是抽象方法),默认是不可被重写的,必须显示的加上关键字 open,才可以被重写。
(3)抽象类中的所有方法,有关键字 abstract 和open的方法,在实现类里边,必须全部被重写,否则不会被编译通过。
(4)继承抽象类写法 class T( ): Aabstract( ) { } ,抽象类后边必须添加括号。
(5)重写抽象类中的方法,跟接口实现一样,在实现类中 也需要添加 关键字 override。
- // Foo类 实现 FooAbstract抽象类、FooInterface接口
- class Foo(val x: String):FooAbstract(), FooInterface{
- // 重写了抽象类中 foo方法
- override fun foo() {
- TODO("Not yet implemented")
- }
- // 重写了接口中 bar方法
- override fun bar() {
- TODO("Not yet implemented")
- }
- }
- // 定义抽象类
- abstract class FooAbstract {
- abstract fun foo()
- }
- // 定义接口
- interface FooInterface{
- fun bar()
- }
1、继承普通类,普通类前边必须添加 open 关键字,才能被别的类继承:
- // Foo类 实现 FooAbstract抽象类、FooInterface接口
- open class Foo(val x: String):FooAbstract(), FooInterface{
- override fun foo() {
- TODO("Not yet implemented")
- }
-
- override fun bar() {
- TODO("Not yet implemented")
- }
- }
- // Foo2 继承 Foo 类,Foo类前边必须添加关键字 open
- class Foo2(val y: String):Foo(y){
- }
- // 定义抽象类
- abstract class FooAbstract {
- abstract fun foo()
- }
- // 定义接口
- interface FooInterface{
- fun bar()
- }
- fun main(){
- Foo2("hello")
- }
2、被继承类中的方法,如果不想被别的类复写某个方法,可以在方法卡那边加上关键字 final
- open class Foo(a:String): FooInterface, FooAbstractClass(){
- override fun foo() {
- TODO("Not yet implemented")
- }
- // bar 方法不可被别的类重写
- final override fun bar() {
- TODO("Not yet implemented")
- }
- }
- class Foo2(val a: String):Foo(a){
- override fun foo() {
- }
- // 编译不会通过,因为Foo类中的bar方法,前边有关键字 final
- override fun bar() {
- }
- }
- abstract class FooAbstractClass {
- abstract fun foo()
- }
- interface FooInterface {
- fun bar()
- }
