类声明

和Java一样,Kotlin中使用关键字class来声明一个类。如下即是声明一个最简单的没有任何属性和方法的类

// 没有任何属性、方法的Invoice 类
class Invoice {}

一个完整的类声明包含类名类头(指定构造参数、构造方法等),类体(用大括号包裹的部分)。类头和类体这两个部分并非必要的,类头和类体都是可选的; 如果一个类没有类体,可以省略花括号。

class Invoice

构造函数

在 Kotlin 中的一个类可以有一个主构造函数和一个或多个次构造函数。主构造函数是类头的一部分:它跟在类名(和可选的类型参数)后。

class Person constructor(firstName: String) {
}

如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字。

class Person(firstName: String) {
}

主构造函数不能包含任何的代码。初始化的代码可以放到以 init 关键字作为前缀的初始化块(initializer blocks)中:


class Customer(p : Int) {
init {
println("Customer类初始化")
}
}

次构造函数

二级构造函数,也称为次级构造函数。关于二级构造函数,主要有以下几点:

  1. 次级构造函数不能省略constructor关键字
  2. 当类拥有主构造函数时,任何一个二级构造函数都需要直接或间接通过另一个二级构造函数代理主构造函数
  3. 类中的一个构造函数代理另一个构造函数,需要使用关键字this

类也可以声明前缀有 constructor次构造函数

class Person {
constructor(parent: Person) {
parent.children.add(this )
}
}
class Person constructor(id: Int) {//(构造函数No.0)主构造函数
var id = id//主构造函数初始化id
var name = ""
var age = 0
//(构造函数No.1)直接代理主构造函数
constructor(name: String, id: Int) : this(id) {
this.name = name
}
//(构造函数No.2)代理了构造函数No.1,间接代理主构造函数
constructor(name: String, age: Int, id: Int) : this(name, id) {
this.age = age
}
}

继承

和所有的Java类都有一个共同的父类Object一样且不支持同时继承多个父类。Kotlin中所有的类都拥有一个共同的父类Any(但Any不是Object,不要搞错)。Any相比Object其内部结构要简单很多,仅有equals()、hashCode()、toString()三个抽象方法。

//默认情况下,在 Kotlin 中所有的类都是 final,
//抽象是面向对象编程的特征之一,类本身,或类中的部分成员,都可以声明为abstract的。抽象成员在类中不存在具体的实现。 open class Base(p: Int){
init {
println("基类")
} //重写
//在基类中,使用fun声明函数时,此函数默认为final修饰,不能被子类重写。
// 如果允许子类重写该函数,那么就要手动添加 open 修饰它, 子类重写方法使用 override 关键词:
open fun sdutent() {
println("基类方法")
}
}
class Customer(p : Int): Base(p) {

    init {
println("Customer类")
} constructor(p: Int,n: String):this(p){
println("$p is n= $n")
} override fun sdutent() {
super.sdutent()
println("重写基类的方法")
}
}

属性和赋值

在声明一个最简单的空壳类之后,我们来为它增加一些类属性。Kotlin中类的属性可以用var或者val关键字进行声明,其中var为可变属性,val为只读属性(相当于Java的final)。


class Student {
var name = "名字" //名字属性可变,用var
val birthday = "1994-10-26" //生日属性不可变,用val
}

像上面这样就简单的为Student类声明了name和birthday两个属性,且在声明属性时进行了初始化,按照Kotlin的类型推断特点,name和birthday就是属于String类型(不知道类型推断的同学可以翻阅前面的写的文章)。现在我想为Student类添加一个age属性,但是我并不想在声明时进行初始化,用Java写起来非常简单即可实现

public class JavaStudent {
private String name = "名字";
private String birthday = "1994-10-26";
private int age;//Java版的实现
}

按照Java的实现套路直接套入Kotlin你会发现IDE直接报错并提示property must be initialized or be abstract

  

按照提示我们必须把类和字段都声明为abstract才可以通过编译。
abstract class Student {
var name = "名字" //名字属性可变,用var
val birthday = "1994-10-26" //生日属性不可变,用val
abstract var age: Int
}

这样未免太过麻烦,而且理解起来也非常奇怪。Kotlin提供了延迟初始化的方式来解决初始化的问题,使用关键字lateinit即可,这样就无需声明abstract了。

可惜使用lateinit延迟初始化age之后,IDE依旧报错,这次提示的内容是lateinit modifier is not allowed on primitive type properties。Kotlin并不支持对原生类型进行lateinit,为什么呢?因为Kotlin会使用null来对每一个用lateinit修饰的属性做初始化,而基础类型是没有null类型,所以无法使用lateinit。这点很好理解,就像可以把int型变量赋值为0,却无法赋值为null一样。所以这里为了通过IDE的编译,我们可以采用两种方案,要么还是直接在age声明时进行初始化,要么不用基础类型来定义age。


class Student {
var name = "名字" //名字属性可变,用var
val birthday = "1994-10-26" //生日属性不可变,用val
var age = 0 //直接使用0初始化age,age为Int型
lateinit var ageStr: String //String不是基础类型,可以使用lateinit初始化
}

创建对象

调用类的构造器,调用方式和使用普通函数一样:

val person = Student ()

注意:Kotlin 没有 new 关键字。

 

Kotlin------类和对象(一)的更多相关文章

  1. Kotlin 类和对象

    类定义 Kotlin 类可以包含:构造函数和初始化代码块.函数.属性.内部类.对象声明. Kotlin 中使用关键字 class 声明类,后面紧跟类名: class Runoob { // 类名为 R ...

  2. Kotlin语法(类和对象)

    二.类和对象: 1. 类定义: 类的声明包含类名,类头(指定类型参数,主构造函数等等),以及类主体,用大括号包裹.类头和类体是可选的:如果没有类体可以省略大括号. class Invoice{ } 2 ...

  3. Kotlin基础(三)类、对象和接口

    类.对象和接口 一.定义类的继承结构 一)Kotlin中的接口 Kotlin的接口与Java8中相似,它们可以包含抽象方法的定义以及非抽象方法的实现,但它们不能包含任何状态. interface Cl ...

  4. 类和对象在JVM中是如何存储的,竟然有一半人回答不上来!

    前言 这篇博客主要来说说类与对象在JVM中是如何存储的,由于JVM是个非常庞大的课题,所以我会把他分成很多章节来细细阐述,具体的数量还没有决定,当然这不重要,重点在于是否可以在文章中学到东西,是否对J ...

  5. Kotlin类:功能更强、而更简洁(KAD 03)

    作者:Antonio Leiva 时间:Dec 7, 2016 原文链接:http://antonioleiva.com/classes-kotlin/ Kotlin类尽可能简单,这样用较少的代码完成 ...

  6. Java编程里的类和对象

    像我们搞计算机这块的,都知道这么一件事,当前的计算机编程语言主要分为两大块,一为面向过程,二为面向对象.Java就是一门纯面向对象的语言.学习了一个月左右的Java,在下对于Java当中的类和对象有了 ...

  7. Python - 类与对象的方法

    类与对象的方法

  8. C++基础知识(5)---类和对象

    终于把C++中的基础在前面的几篇博客中总结完了,可能还有一些语法还没有总结到,没关系,以后用到了再查资料就好.类是C++中的一个非常重要的概念,这是区别你使用的C++到底是面向过程还是面向对象的一个重 ...

  9. 简述JavaScript对象、数组对象与类数组对象

    问题引出 在上图给出的文档中,用JavaScript获取那个a标签,要用什么办法呢?相信第一反应一定是使用document.getElementsByTagName('a')[0]来获取.同样的,在使 ...

  10. 前端学PHP之面向对象系列第一篇——类和对象

    × 目录 [1]类 [2]成员属性[3]成员方法[4]对象[5]成员访问[6]this 前面的话 面向对象程序设计(OOP)是一种计算机编程架构.计算机程序由单个能够起到子程序作用的单元或对象组成,为 ...

随机推荐

  1. Delphi APP 開發入門(八)SQLite資料庫

    Delphi APP 開發入門(八)SQLite資料庫 分享: Share on facebookShare on twitterShare on google_plusone_share   閲讀次 ...

  2. 性能调优之MySQL篇一:MySQL性能计数器

    计数器 计数器分析 Threads_connected 表示当前有多少个客户连接该mysql服务器,连接数是否过多,网络是否存在问题,它是动态变化的,当达到最大连接数时,数据库系统就不能提供更多的连接 ...

  3. Java并发编程:并发容器之ConcurrentHashMap(转)

    本文转自:http://www.cnblogs.com/dolphin0520/p/3932905.html Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载 ...

  4. dubbo-admin 监控中心 部署

    dubbo-admin部署 下载: GitHub:https://github.com/search?q=dubbo-admin 百度网盘: 链接:https://pan.baidu.com/s/1v ...

  5. CSS3 Gradients(渐变)

    CSS3 Gradients(渐变) 一.简介 CSS3 渐变(gradients)可以让你在两个或多个指定的颜色之间显示平稳的过渡. 以前,你必须使用图像来实现这些效果.但是,通过使用 CSS3 渐 ...

  6. CSS Dimension(尺寸)

    CSS Dimension(尺寸) 一.简介 CSS 尺寸 (Dimension) 属性允许你控制元素的高度和宽度.同样,它允许你增加行间距. 二.Dimension(尺寸)属性值 三.示例 (1)示 ...

  7. Python3.x:代理ip刷点赞

    Python3.x:代理ip刷点赞 声明:仅供为学习材料,不允许用作商业用途: 一,功能: 针对某网站对企业自动刷点赞: 网站:https://best.zhaopin.com/ 二,步骤: 1,获取 ...

  8. javascript里用php

    <script type="text/javascript" > <?php if (!empty($searchResult)):?> $.searchM ...

  9. ES6、7、8常用新特性总结(超实用)

    ES6常用新特性 1. let && const let 命令也用于变量声明,但是作用域为局部 { let a = 10; var b = 1; } 在函数外部可以获取到b,获取不到a ...

  10. 20145301实验五 Java网络编程及安全

    北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1453 指导教师:娄嘉鹏 实验日期:2016.05.06 18:30-21:30 实验名称:实验五 Java网络编程 实验内容 ...