拉不拉稀肚拉稀 发表于 2025-1-26 03:32:05

Kotlin基础知识学习(四)

类和对象

类的构造

定义



[*]类也是用关键字class修饰。
[*]如果是public修饰的类,public可以省略
[*]用:表示类的继承。
[*]继承必要在类背面加上()。
[*]创建类实例时不必要new。
[*]init{}表示类初始化模块。
/**
* 1、如果是public修饰的类,public可以省略
* 2、用:表示类的继承
* 3、继承需要在类后面加上()
*/
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
      super.onCreate(savedInstanceState, persistentState)
    }
}
class Shape {
    /**
   * 初始化函数属于构造函数的一部分
   */
    init {
      println("Shape是表示形状的类")
    }
}
构造函数

主构造函数



[*]主构造函数,放在类名背面,用constructor修饰。
[*]没有带@符号修饰的,constructor可以省略。
[*]主构造函数不是必须的。
/*
* 主构造函数,放在类名后面
* */
class Shape1(name:String) {
    /**
   * 初始化函数属于构造函数的一部分
   */
    init {
      println("Shape1是表示形状的类,名称是$name")
    }
}
class Shape1 constructor(name:String) {

}
//只有带参的主构造函数,创建需要参数声明
    var shape1 = Shape1("通用形状")
次构造函数



[*]没有名称。
[*]用关键字constructor修饰。
[*]如果有主构造函数必要调用主构造函数。
[*]会先调用主构造函数的初始化函数。
/*
* 主构造函数,放在类名后面
* */
class Shape2(name:String) {
    /**
   * 初始化函数属于构造函数的一部分
   */
    init {
      println("Shape2是表示形状的类,名称是$name")
    }

    /*
    * 二级构造造函数
    * 1、没有名称
    * 2、用关键字constructor修饰
    * 3、需要调用主构造函数
    * 4、会先调用主构造函数的初始化函数
    * */
    constructor(name:String,side:Int) : this(name) {
      println("Shape2是表示形状的类,名称是$name,是${side}边形")
    }
}

    //有主构造和二级构造,可以用两种方式声明
    var shape2 = Shape2("通用形状")
    var shape3 = Shape2("通用形状",4)
/**
* 没有主构造函数
*/
class Shape3 {

    init {
      println("Shape3是表示形状的类")
    }

    constructor() {
      println("Shape3是表示形状的类,无参")
    }

    constructor(name:String) {
      println("Shape3是表示形状的类,名称是$name")
    }

    constructor(name:String,side:Int) {
      println("Shape3是表示形状的类,名称是$name,是${side}边形")
    }

}
    //只有二级构造函数,会先调用初始化函数
    var shape4 = Shape3()
    var shape5 = Shape3("通用形状")
    var shape6 = Shape3("通用形状",5)
参数带默认值的造函数



[*]构造函数的参数可以带默认值。
class Shape4 {
    /**
   * 初始化函数属于构造函数的一部分
   */
    init {
      println("Shape4是表示形状的类")
    }

    /**
   * 带默认参数的构造函数
   */
    constructor(name:String,side:Int = 6) {
      println("Shape4是表示形状的类,名称是$name,是${side}边形")
    }

}
    //参数带带默认值,创建的时候可以不用传
    var shape7 = Shape4("通用形状")
    var shape8 = Shape4("通用形状",8)


[*]如果要兼容Java创建实例的时间也能用默认参数,则必要加上@JvmOverloads修饰,否则编译会堕落。
class Shape5 {
    /**
   * 初始化函数属于构造函数的一部分
   */
    init {
      println("Shape5是表示形状的类")
    }

    /**
   * 带默认参数的构造函数
   * 如果要兼容Java创建实例的时候也能用默认参数,则需要加上@JvmOverloads修饰
   * 否则编译会出错
   */
    @JvmOverloads constructor(name:String,side:Int = 6) {
      println("Shape5是表示形状的类,名称是$name,是${side}边形")
    }

}
      //java形式创建
      Shape5 shape4 = new Shape5("通用形状");
类的成员

属性



[*]在类里面定义属性,在init模块里面初始化属性。
/*
* 在类里面定义属性,在init模块里面初始化属性
* */
class People (name:String,age:Int){
    //成员属性
    var name:String
    var age:Int

    init {
      //初始化
      this.name = name
      this.age = age
    }
}
    var people = People("张三",18)
    //属性访问
    people.age = 19
    println(people.age )//19
    println(people.name )//张三


[*]直接在主构造函数里面声明属性。
/*
* 直接在主构造函数里面声明属性
* */
class People1 (var name:String, var age:Int){

}
    var people1 = People1("李四",18)
    println(people1.age )//18
    println(people1.name )//李四
方法



[*]用fun修饰表示方法。
[*]调用也是通过.方法名。
/*
* 直接在主构造函数里面声明属性
* */
class People1 (var name:String, var age:Int){
    fun getName():String {
      return name
    }

    fun getAge():Int {
      return age
    }
}
    var people1 = People1("李四",18)
    println(people1.getName())//李四
    println(people1.getAge())//18
伴生对象



[*]利用伴生对象来模拟静态属性和方法。
[*]伴生对象中的属性和方法可以通过类名直接访问。
[*]用companion object举行修饰。
    /*
    * companion object表示半生对象,相当于Java中的静态
    * */
    companion object {
      //属性
      var speciesCount:Int = 0
      //方法
      fun judgeSex(sex:Int):Int {
            var sexName:String = when (sex) {
                0 -> "女"
                1 -> "男"
                else -> ""
            }
            return sex
      }
    }
    //用类名直接访问
    People2.speciesCount
    People2.judgeSex(people2.sex)
类的继承、抽象、接口

开放修饰符

修饰符说明public公共开放,默认是publicinternal本模块内能访问protected本身和其子类private私有 继承



[*]默认不能被继承。
[*]类要能被继承必要声明open类型。
[*]private和open不能共存。
[*]父类中如果方法允许被重写,方法也得加上open。
[*]用:表示继承。
[*]方法重写必要加上override关键字。
[*]不允许多继承即同时继承多个类。
/*
* class前面加上open表示允许被继承
* */
open class People (var name:String, var age:Int){
    protected var height:Double = 0.0
    private var sex:Int = 0

    /*
    * 加上open方法才能被重写
    * */
    open fun eat() {
      println("${name}正在吃饭")
    }

    protected open fun introduce() {
      println("我是个好人")
    }

    fun setSex(sex:Int){
      this.sex = sex
    }
}
/*
* 继承用:表示
* */
class Student(name:String,age:Int) : People(name,age) {
    /*
    * 方法重写在方法前面加上override
    * */
    override fun eat(){
      introduce()
      println("学生${name}正在吃饭")
    }

    override fun introduce(){
      println("我是个好学生")
    }

}
抽象类



[*]抽象类用关键字abstract修饰。
[*]抽象类不一定有抽象方法,但有抽象方法的必须是抽象类。
[*]可以有非抽象的方法。
[*]抽象类和方法必要被实现,所以open关键字可以不写。
/*
* 定义形状抽象类Shape
* 1、抽象类用关键字abstract修饰
* 2、抽象类不一定有抽象方法,但有抽象方法的必须是抽象类
* 3、可以有非抽象的方法
* */
abstract class Shape {
    /*
    * 抽象方法
    * */
    abstract fun draw()

    /*
    * 非抽象方法
    * */
    open fun area(): Double {
      throw UnsupportedOperationException("This method should be overridden by subclasses")
    }
}

class Circle(val radius:Double) : Shape(){

    /*
    * 方法重写
    * */
    override fun draw() {
      println("画一个圆")
    }

    override fun area(): Double {
      return Math.PI * radius * radius
    }
}
class Rectangle(val width: Double, val height: Double) : Shape(){
    override fun draw() {
      println("画一个长方形")
    }

    override fun area(): Double {
      return width * height
    }
}
    val circle = Circle(10.0)
    circle.draw()//画一个圆
    println("圆的面积是${circle.area()}")//圆的面积是314.1592653589793

    val rectangle = Rectangle(10.0, 10.0)
    rectangle.draw()//画一个长方形
    println("长方形的面积是${rectangle.area()}")//长方形的面积是100.0
接口



[*]用interface表示接口
[*]接口不能有构造函数,否则会报错。
[*]没实现的方法默认是抽象,所以open可以省略。
[*]允许有实现的方法。
[*]也是用:表示实现接口。
* 用interface表示接口
* 1、接口不能有构造函数,否则会报错。
* 2、没实现的方法默认是抽象,所以open可以省略。
* 3、允许有实现的方法。
* */
interface Animal {
    fun eat()
    fun makeSound()

    fun common(name:String){
      println("${name}是一只可爱的动物")
    }
}
class Dog : Animal{
    override fun eat() {
      println("狗正在吃饭")
    }

    override fun makeSound() {
      println("狗正在汪汪叫")
    }

}
class Cat : Animal{
    override fun eat() {
      println("猫正在吃饭")
    }

    override fun makeSound() {
      println("猫正在喵喵叫")
    }
}
特殊类

嵌套类



[*]在外部内定义一个类,嵌套类不能访问外部类的属性、方法等。
[*]调用嵌套类时通过调用嵌套类时通过(外部类名称.内部类),相当是外部类的静态内部类。
class Outer(var name:String) {
    fun outFunction(){

    }

    //嵌套类
    class NestedInObject(var nestedName:String) {
      fun nestedFunction() {
            //不能访问外部类的属性和方法
            //println(name)
            //outFunction()
      }
    }
}
    //调用嵌套类时通过(外部类名称.内部类)
    // 相当是外部类的静态内部类
    Outer.NestedInObject("嵌套类")
内部类



[*]在类内部定义一个类,且用inner举行修饰,称为内部类。
[*]内部类可以访问外部类的属性。
[*]调用内部类必要先创建外部类。
class OuterInner(var name:String) {
    fun outFunction(){
      println("outFunction")
    }

    //用inner表示是内部类
    inner class Inner(var innerName:String){
      fun innerFunction(){
            println("$innerName")
            //可以访问外部类的属性
            println("$name")
            outFunction()
      }
    }
}
    //访问内部类需要先创建内部类
    val inner = OuterInner("外部类").Inner("内部类")
    inner.innerFunction()
枚举类



[*]通过enmu修饰,用于定义一组常量。
enum class Color {
    RED, GREEN, BLUE
}
    //直接访问
    val red = Color.RED
    println(red)//RED
    println(red.name)


[*]遍历枚举
    //遍历枚举
    for (color in Color.values()) {
      println(color)
    }


[*]可以添加属性
/**
* 可以添加属性
*/
enum class Planet(val mass: Double, val radius: Double) {
    MERCURY(3.303e+23, 2.4397e6),
    VENUS(4.869e+24, 6.0518e6),
    EARTH(5.976e+24, 6.37814e6);

}
println(Planet.EARTH.mass)


[*]添加方法
/**
* 可以添加方法
*/
enum class Operation {
    PLUS {
      override fun apply(x: Int, y: Int) = x + y
    },
    MINUS {
      override fun apply(x: Int, y: Int) = x - y
    },
    TIMES {
      override fun apply(x: Int, y: Int) = x * y
    },
    DIVIDE {
      override fun apply(x: Int, y: Int): Int {
            return if (y == 0) throw ArithmeticException("Division by zero") else x / y
      }
    };

    abstract fun apply(x: Int, y: Int): Int
}
Operation.PLUS.apply(10,20)
数据类



[*]一种用于存储数据的特殊类,其重要目的是简化数据持有者的实现。
[*]数据类会自动为你天生一些常用的方法,比如 equals()、hashCode() 和 toString(),以及 copy() 方法(用于复制对象并修改其部分属性)。
[*]用data修饰,必要有主构造函数。
data class Person(val name:String,val age:Int)
    val person = Person("张三", 19)
    val copy = person.copy()
    person.equals(copy)
    person.toString()
密封类



[*]一种用于表示受限的类继承结构的特殊类。
[*]密封类可以有一个或多个子类,但所有这些子类必须在同一个文件中声明。 这意味着你不能在密封类声明的文件之外继承它。
[*]密封类常用于表示一组受限的、相关的类,比方状态、变乱或者消息类型。
[*]密封类的重要用途之一是提供更强的类型安全性,在 when 表达式中尤为显着。当你利用密封类时,编译器可以确保你已经覆盖了所有可能的子类,从而制止利用 else 分支或者处理未预期的类型。
sealed class OrderStatus {
    object Pending : OrderStatus()
    object Shipped : OrderStatus()
    object Delivered : OrderStatus()
    object Cancelled : OrderStatus()
}

fun printOrderStatus(status: OrderStatus) {
    when (status) {
      is OrderStatus.Pending -> println("Order is pending.")
      is OrderStatus.Shipped -> println("Order has been shipped.")
      is OrderStatus.Delivered -> println("Order has been delivered.")
      is OrderStatus.Cancelled -> println("Order has been cancelled.")
    }
}

fun main() {
    val status = OrderStatus.Shipped
    printOrderStatus(status)
}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Kotlin基础知识学习(四)