Kotlin基础知识学习(四)

打印 上一主题 下一主题

主题 1670|帖子 1670|积分 5012

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
类和对象

类的构造

定义



  • 类也是用关键字class修饰。
  • 如果是public修饰的类,public可以省略
  • 用:表示类的继承。
  • 继承必要在类背面加上()。
  • 创建类实例时不必要new。
  • init{}表示类初始化模块。
  1. /**
  2. * 1、如果是public修饰的类,public可以省略
  3. * 2、用:表示类的继承
  4. * 3、继承需要在类后面加上()
  5. */
  6. class MainActivity : AppCompatActivity() {
  7.     override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
  8.         super.onCreate(savedInstanceState, persistentState)
  9.     }
  10. }
复制代码
  1. class Shape {
  2.     /**
  3.      * 初始化函数属于构造函数的一部分
  4.      */
  5.     init {
  6.         println("Shape是表示形状的类")
  7.     }
  8. }
复制代码
构造函数

主构造函数



  • 主构造函数,放在类名背面,用constructor修饰。
  • 没有带@符号修饰的,constructor可以省略。
  • 主构造函数不是必须的。
  1. /*
  2. * 主构造函数,放在类名后面
  3. * */
  4. class Shape1(name:String) {
  5.     /**
  6.      * 初始化函数属于构造函数的一部分
  7.      */
  8.     init {
  9.         println("Shape1是表示形状的类,名称是$name")
  10.     }
  11. }
复制代码
  1. class Shape1 constructor(name:String) {
  2. }
复制代码
  1. //只有带参的主构造函数,创建需要参数声明
  2.     var shape1 = Shape1("通用形状")
复制代码
次构造函数



  • 没有名称。
  • 用关键字constructor修饰。
  • 如果有主构造函数必要调用主构造函数。
  • 会先调用主构造函数的初始化函数。
  1. /*
  2. * 主构造函数,放在类名后面
  3. * */
  4. class Shape2(name:String) {
  5.     /**
  6.      * 初始化函数属于构造函数的一部分
  7.      */
  8.     init {
  9.         println("Shape2是表示形状的类,名称是$name")
  10.     }
  11.     /*
  12.     * 二级构造造函数
  13.     * 1、没有名称
  14.     * 2、用关键字constructor修饰
  15.     * 3、需要调用主构造函数
  16.     * 4、会先调用主构造函数的初始化函数
  17.     * */
  18.     constructor(name:String,side:Int) : this(name) {
  19.         println("Shape2是表示形状的类,名称是$name,是${side}边形")
  20.     }
  21. }
复制代码
  1.     //有主构造和二级构造,可以用两种方式声明
  2.     var shape2 = Shape2("通用形状")
  3.     var shape3 = Shape2("通用形状",4)
复制代码
  1. /**
  2. * 没有主构造函数
  3. */
  4. class Shape3 {
  5.     init {
  6.         println("Shape3是表示形状的类")
  7.     }
  8.     constructor() {
  9.         println("Shape3是表示形状的类,无参")
  10.     }
  11.     constructor(name:String) {
  12.         println("Shape3是表示形状的类,名称是$name")
  13.     }
  14.     constructor(name:String,side:Int) {
  15.         println("Shape3是表示形状的类,名称是$name,是${side}边形")
  16.     }
  17. }
复制代码
  1.     //只有二级构造函数,会先调用初始化函数
  2.     var shape4 = Shape3()
  3.     var shape5 = Shape3("通用形状")
  4.     var shape6 = Shape3("通用形状",5)
复制代码
参数带默认值的造函数



  • 构造函数的参数可以带默认值。
  1. class Shape4 {
  2.     /**
  3.      * 初始化函数属于构造函数的一部分
  4.      */
  5.     init {
  6.         println("Shape4是表示形状的类")
  7.     }
  8.     /**
  9.      * 带默认参数的构造函数
  10.      */
  11.     constructor(name:String,side:Int = 6) {
  12.         println("Shape4是表示形状的类,名称是$name,是${side}边形")
  13.     }
  14. }
复制代码
  1.     //参数带带默认值,创建的时候可以不用传
  2.     var shape7 = Shape4("通用形状")
  3.     var shape8 = Shape4("通用形状",8)
复制代码


  • 如果要兼容Java创建实例的时间也能用默认参数,则必要加上@JvmOverloads修饰,否则编译会堕落。
  1. class Shape5 {
  2.     /**
  3.      * 初始化函数属于构造函数的一部分
  4.      */
  5.     init {
  6.         println("Shape5是表示形状的类")
  7.     }
  8.     /**
  9.      * 带默认参数的构造函数
  10.      * 如果要兼容Java创建实例的时候也能用默认参数,则需要加上@JvmOverloads修饰
  11.      * 否则编译会出错
  12.      */
  13.     @JvmOverloads constructor(name:String,side:Int = 6) {
  14.         println("Shape5是表示形状的类,名称是$name,是${side}边形")
  15.     }
  16. }
复制代码
  1.         //java形式创建
  2.         Shape5 shape4 = new Shape5("通用形状");
复制代码
类的成员

属性



  • 在类里面定义属性,在init模块里面初始化属性。
  1. /*
  2. * 在类里面定义属性,在init模块里面初始化属性
  3. * */
  4. class People (name:String,age:Int){
  5.     //成员属性
  6.     var name:String
  7.     var age:Int
  8.     init {
  9.         //初始化
  10.         this.name = name
  11.         this.age = age
  12.     }
  13. }
复制代码
  1.     var people = People("张三",18)
  2.     //属性访问
  3.     people.age = 19
  4.     println(people.age )//19
  5.     println(people.name )//张三
复制代码


  • 直接在主构造函数里面声明属性。
  1. /*
  2. * 直接在主构造函数里面声明属性
  3. * */
  4. class People1 (var name:String, var age:Int){
  5. }
复制代码
  1.     var people1 = People1("李四",18)
  2.     println(people1.age )//18
  3.     println(people1.name )//李四
复制代码
方法



  • 用fun修饰表示方法。
  • 调用也是通过.方法名。
  1. /*
  2. * 直接在主构造函数里面声明属性
  3. * */
  4. class People1 (var name:String, var age:Int){
  5.     fun getName():String {
  6.         return name
  7.     }
  8.     fun getAge():Int {
  9.         return age
  10.     }
  11. }
复制代码
  1.     var people1 = People1("李四",18)
  2.     println(people1.getName())//李四
  3.     println(people1.getAge())//18
复制代码
伴生对象



  • 利用伴生对象来模拟静态属性和方法。
  • 伴生对象中的属性和方法可以通过类名直接访问。
  • 用companion object举行修饰。
  1.     /*
  2.     * companion object表示半生对象,相当于Java中的静态
  3.     * */
  4.     companion object {
  5.         //属性
  6.         var speciesCount:Int = 0
  7.         //方法
  8.         fun judgeSex(sex:Int):Int {
  9.             var sexName:String = when (sex) {
  10.                 0 -> "女"
  11.                 1 -> "男"
  12.                 else -> ""
  13.             }
  14.             return sex
  15.         }
  16.     }
复制代码
  1.     //用类名直接访问
  2.     People2.speciesCount
  3.     People2.judgeSex(people2.sex)
复制代码
类的继承、抽象、接口

开放修饰符

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



  • 默认不能被继承。
  • 类要能被继承必要声明open类型。
  • private和open不能共存。
  • 父类中如果方法允许被重写,方法也得加上open。
  • 用:表示继承。
  • 方法重写必要加上override关键字。
  • 不允许多继承即同时继承多个类。
  1. /*
  2. * class前面加上open表示允许被继承
  3. * */
  4. open class People (var name:String, var age:Int){
  5.     protected var height:Double = 0.0
  6.     private var sex:Int = 0
  7.     /*
  8.     * 加上open方法才能被重写
  9.     * */
  10.     open fun eat() {
  11.         println("${name}正在吃饭")
  12.     }
  13.     protected open fun introduce() {
  14.         println("我是个好人")
  15.     }
  16.     fun setSex(sex:Int){
  17.         this.sex = sex
  18.     }
  19. }
复制代码
  1. /*
  2. * 继承用:表示
  3. * */
  4. class Student(name:String,age:Int) : People(name,age) {
  5.     /*
  6.     * 方法重写在方法前面加上override
  7.     * */
  8.     override fun eat(){
  9.         introduce()
  10.         println("学生${name}正在吃饭")
  11.     }
  12.     override fun introduce(){
  13.         println("我是个好学生")
  14.     }
  15. }
复制代码
抽象类



  • 抽象类用关键字abstract修饰。
  • 抽象类不一定有抽象方法,但有抽象方法的必须是抽象类。
  • 可以有非抽象的方法。
  • 抽象类和方法必要被实现,所以open关键字可以不写。
  1. /*
  2. * 定义形状抽象类Shape
  3. * 1、抽象类用关键字abstract修饰
  4. * 2、抽象类不一定有抽象方法,但有抽象方法的必须是抽象类
  5. * 3、可以有非抽象的方法
  6. * */
  7. abstract class Shape {
  8.     /*
  9.     * 抽象方法
  10.     * */
  11.     abstract fun draw()
  12.     /*
  13.     * 非抽象方法
  14.     * */
  15.     open fun area(): Double {
  16.         throw UnsupportedOperationException("This method should be overridden by subclasses")
  17.     }
  18. }
复制代码
  1. class Circle(val radius:Double) : Shape(){
  2.     /*
  3.     * 方法重写
  4.     * */
  5.     override fun draw() {
  6.         println("画一个圆")
  7.     }
  8.     override fun area(): Double {
  9.         return Math.PI * radius * radius
  10.     }
  11. }
复制代码
  1. class Rectangle(val width: Double, val height: Double) : Shape(){
  2.     override fun draw() {
  3.         println("画一个长方形")
  4.     }
  5.     override fun area(): Double {
  6.         return width * height
  7.     }
  8. }
复制代码
  1.     val circle = Circle(10.0)
  2.     circle.draw()//画一个圆
  3.     println("圆的面积是${circle.area()}")//圆的面积是314.1592653589793
  4.     val rectangle = Rectangle(10.0, 10.0)
  5.     rectangle.draw()//画一个长方形
  6.     println("长方形的面积是${rectangle.area()}")//长方形的面积是100.0
复制代码
接口



  • 用interface表示接口
  • 接口不能有构造函数,否则会报错。
  • 没实现的方法默认是抽象,所以open可以省略。
  • 允许有实现的方法。
  • 也是用:表示实现接口。
  1. * 用interface表示接口
  2. * 1、接口不能有构造函数,否则会报错。
  3. * 2、没实现的方法默认是抽象,所以open可以省略。
  4. * 3、允许有实现的方法。
  5. * */
  6. interface Animal {
  7.     fun eat()
  8.     fun makeSound()
  9.     fun common(name:String){
  10.         println("${name}是一只可爱的动物")
  11.     }
  12. }
复制代码
  1. class Dog : Animal{
  2.     override fun eat() {
  3.         println("狗正在吃饭")
  4.     }
  5.     override fun makeSound() {
  6.         println("狗正在汪汪叫")
  7.     }
  8. }
复制代码
  1. class Cat : Animal{
  2.     override fun eat() {
  3.         println("猫正在吃饭")
  4.     }
  5.     override fun makeSound() {
  6.         println("猫正在喵喵叫")
  7.     }
  8. }
复制代码
特殊类

嵌套类



  • 在外部内定义一个类,嵌套类不能访问外部类的属性、方法等。
  • 调用嵌套类时通过调用嵌套类时通过(外部类名称.内部类),相当是外部类的静态内部类。
  1. class Outer(var name:String) {
  2.     fun outFunction(){
  3.     }
  4.     //嵌套类
  5.     class NestedInObject(var nestedName:String) {
  6.         fun nestedFunction() {
  7.             //不能访问外部类的属性和方法
  8.             //println(name)
  9.             //outFunction()
  10.         }
  11.     }
  12. }
复制代码
  1.     //调用嵌套类时通过(外部类名称.内部类)
  2.     // 相当是外部类的静态内部类
  3.     Outer.NestedInObject("嵌套类")
复制代码
内部类



  • 在类内部定义一个类,且用inner举行修饰,称为内部类。
  • 内部类可以访问外部类的属性。
  • 调用内部类必要先创建外部类。
  1. class OuterInner(var name:String) {
  2.     fun outFunction(){
  3.         println("outFunction")
  4.     }
  5.     //用inner表示是内部类
  6.     inner class Inner(var innerName:String){
  7.         fun innerFunction(){
  8.             println("$innerName")
  9.             //可以访问外部类的属性
  10.             println("$name")
  11.             outFunction()
  12.         }
  13.     }
  14. }
复制代码
  1.     //访问内部类需要先创建内部类
  2.     val inner = OuterInner("外部类").Inner("内部类")
  3.     inner.innerFunction()
复制代码
枚举类



  • 通过enmu修饰,用于定义一组常量。
  1. enum class Color {
  2.     RED, GREEN, BLUE
  3. }
复制代码
  1.     //直接访问
  2.     val red = Color.RED
  3.     println(red)//RED
  4.     println(red.name)
复制代码


  • 遍历枚举
  1.     //遍历枚举
  2.     for (color in Color.values()) {
  3.         println(color)
  4.     }
复制代码


  • 可以添加属性
  1. /**
  2. * 可以添加属性
  3. */
  4. enum class Planet(val mass: Double, val radius: Double) {
  5.     MERCURY(3.303e+23, 2.4397e6),
  6.     VENUS(4.869e+24, 6.0518e6),
  7.     EARTH(5.976e+24, 6.37814e6);
  8. }
复制代码
  1. println(Planet.EARTH.mass)
复制代码


  • 添加方法
  1. /**
  2. * 可以添加方法
  3. */
  4. enum class Operation {
  5.     PLUS {
  6.         override fun apply(x: Int, y: Int) = x + y
  7.     },
  8.     MINUS {
  9.         override fun apply(x: Int, y: Int) = x - y
  10.     },
  11.     TIMES {
  12.         override fun apply(x: Int, y: Int) = x * y
  13.     },
  14.     DIVIDE {
  15.         override fun apply(x: Int, y: Int): Int {
  16.             return if (y == 0) throw ArithmeticException("Division by zero") else x / y
  17.         }
  18.     };
  19.     abstract fun apply(x: Int, y: Int): Int
  20. }
复制代码
  1. Operation.PLUS.apply(10,20)
复制代码
数据类



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



  • 一种用于表示受限的类继承结构的特殊类。
  • 密封类可以有一个或多个子类,但所有这些子类必须在同一个文件中声明。 这意味着你不能在密封类声明的文件之外继承它。
  • 密封类常用于表示一组受限的、相关的类,比方状态、变乱或者消息类型。
  • 密封类的重要用途之一是提供更强的类型安全性,在 when 表达式中尤为显着。当你利用密封类时,编译器可以确保你已经覆盖了所有可能的子类,从而制止利用 else 分支或者处理未预期的类型。
  1. sealed class OrderStatus {
  2.     object Pending : OrderStatus()
  3.     object Shipped : OrderStatus()
  4.     object Delivered : OrderStatus()
  5.     object Cancelled : OrderStatus()
  6. }
  7. fun printOrderStatus(status: OrderStatus) {
  8.     when (status) {
  9.         is OrderStatus.Pending -> println("Order is pending.")
  10.         is OrderStatus.Shipped -> println("Order has been shipped.")
  11.         is OrderStatus.Delivered -> println("Order has been delivered.")
  12.         is OrderStatus.Cancelled -> println("Order has been cancelled.")
  13.     }
  14. }
  15. fun main() {
  16.     val status = OrderStatus.Shipped
  17.     printOrderStatus(status)
  18. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

拉不拉稀肚拉稀

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表