Kotlin基础(三)类、对象和接口
类、对象和接口
一、定义类的继承结构
一)Kotlin中的接口
Kotlin的接口与Java8中相似,它们可以包含抽象方法的定义以及非抽象方法的实现,但它们不能包含任何状态。
interface Clickable{
fun click()
fun showoff()=println("It's show time!")
}
interface Focusable{
fun setFocus(b: Boolean)=
println("I ${if (b) "got" else "lost"} focus.")
fun showoff()= println("Kotlin")
}
class Button: Clickable, Focusable{
//override用法同Java@Override但为强制要求
override fun click() {
println("I was clicked!")
}
//这里如果没有显示地实现showoff,会得到编译错误
override fun showoff(){
//Java中的用法:Clickable.super.showoff();
/*super<Clickable>.showoff()
super<Focusable>.showoff()*/
println("Method of son.")
}
}
二)控制继承的修饰符:open、final和abstract:默认为final
/**
* Java中的类和方法默认是open的,而Kotlin中默认是final的。
* 如果你想允许一个类创建一个子类,需要使用open修饰符来标识这个类
* 方法与属性也是如此。
* */
open class Button: Clickable{
//这个函数是open的
override fun click() {
println("Clicking it")
}
//这个函数不再是open的了
final override fun showoff()= println("Show off")
open fun animate(){}
} /**
* abstract类与Java中的相同,不能被实例化。
*
* */
abstract class Animated{
//这个函数是抽象的,必须被子类实现,所以也是open的
abstract fun animated() //抽象类中的非抽象函数并不是默认open的,但可以标注为open的
open fun stopAnimating()= println("Stop it!")
}
三)可见性修饰符:public,protected,internal和private,默认为public
可见性修饰符帮助控制对代码库中声明的访问。Java中默认可见性为-----包私有,在Kotlin只把包作为在命名空间里组织代码的一种方式使用,并没有将其用作可见性控制。
作为替代Kotlin中提供了一种新的修饰符---internal,表示"只在模块(一组一起编译的Kotlin文件)内部可见"。另外一个区别就是Kotlin允许在顶层声明中使用private可见性,
使这些声明只会在声明他们的文件中可见。
open internal class Button{
private fun click()= println("Hey!")
protected fun showoff()= println("show it")
}
/*
fun Button.fMethod(){ //错误:public成员暴露了其"internal"接收者类型B
yell() //错误
showoff() //错误
}
*/
internal fun Button.fMethod(){
/*showoff() 任然错误*/
}
另一个与Java可见性不同的是:一个外部类不能看到其内部类或嵌套类中的private成员。
四)内部类和嵌套类:默认为嵌套类
只需要记住Kotlin中没有显示修饰符的嵌套类与Java中的static嵌套类是一样的,如果要使其持有外部类的引用的话需要使用inner修饰符。
引用外部类实例语法:this@outer
五)密封类:定义受限的类继承结构
为父类添加一个sealed修饰符,对可能创建的子类做出严格限制,所有的直接子类必须嵌套在父类中。
请思考这样做的好处。
二、声明一个带默认构造方法或属性的类
一)初始化类:主构造方法和初始化语句块
class User0(val name: String="tang"/*可提供默认值*/) /*简便写法,其中val关键字意味着
相应的属性会用构造方法的参数来初始化*/ open class User constructor(name: String)/*带参数的主构造方法,constructor
用来声明一个主构造方法和一个从构造方法*/{
val name:String init { //初始化语句块,因为主构造方法的语法限制,所有有了初始化语句
//一个类中可以声明多个初始化语句
this.name=name
}
} //如果一个类具有父类,主构造方法同样需要初始化父类。
// 即使父类构造函数没有任何参数,也要显示地调用构造函数。
class TwitterUser(name: String) : User(name){} //如果要确保类不被实例化,可以把构造函数标记为private
class Person private constructor(val name: String)
二)构造方法:用不同的方法来初始化父类
//没有主构造函数
open class View{
constructor(ctx: String)
constructor(ctx: String, attr: String)
} class MyButton : View{
constructor(ctx: String) :this(ctx,"s") constructor(ctx: String,attr: String) : super(ctx,attr){
/*some code*/
}
}
三)实现在接口中声明的属性
/*接口可以包含抽象属性声明*/
interface User{
val nickname: String
/*接口还可包含具有getter和setter的属性,只要他们没有引用一个支持字段*/
val age: Int
get() = Random().nextInt(100)
} /*在实现了接口的类中必须override该属性*/
class QQUser (override val nickname: String) : User class BaiduUser(val email: String) : User{
override val nickname: String
get() = "Baidu $email"
}
四)通过getter或setter访问支持字段
class User(val name: String){
var address: String="unspecified"
//在set函数体中,使用了标识符field来访问支持字段的值。
//在get函数中只能读取它,在set函数中可以修改它。
set(value: String) {
println("""
Address was changed for $name: "$field" -> "$value".""".trimIndent())
}
}
fun main(args: Array<String>) {
val user=User("Tom")
user.address="Back Street 221"
user.address="Beijing hu tong 222"
/*Address was changed for Tom: "unspecified" -> "Back Street 221".
Address was changed for Tom: "unspecified" -> "Beijing hu tong 222".*/
}
五)修改访问其可见性
class LengthCounter{
var counter: Int=0
private set //声明为private,不能再类外部修改这个属性
fun addWord(word: String){
counter+=word.length
}
}
三、编译器生成的方法:数据类和类委托
一)通用的对象方法
1.toString()
2.equals():在Kotlin中"=="相当于Java中的equals,"==="相当于Java中的"=="(比较引用)
3.hashCode()方法通常与equals方法一起被重写(如果两个对象相等,它们通常必须有相同的hash值)。
class Client(val name: String,val postalCode: Int){
override fun equals(other: Any?): Boolean {
if (other==null || other !is Client) return false
return name==other.name && postalCode==other.postalCode
}
override fun toString(): String {
return "Client($name,$postalCode)"
}
override fun hashCode(): Int {
return name.hashCode()*12+postalCode
}
}
二)数据类:自动生成通用方法实现
如果为类添加data修饰符,上述通用方法将会被自动生成好。其中
1.equals方法:检测所以主构造函数属性的值是否相等。
2.hashCode方法:返回一个根据所有主构造函数中属性值生成的哈希值。
注意:没有在主构造函数中声明的属性将不会加入到相等性检测和哈希值计算中去。
data class User(val name: String,val age:Int,val gender: String)
三)类委托:使用"by"关键字
class TangCollection<T>(
val innerList: Collection<T> = ArrayList<T>()
) : Collection<T> by innerList {}
四)"object"关键字:将声明一个类与创建一个实例结合起来
object关键字:定义一个类的同时创建一个实例
一)对象声明:创建单例
/*
* 在定义的时候就被创建,并且为一个单例
* */
object User {
val name: String = "Tang"
val age: Int = 8
}
二)伴生对象:工厂方法和静态成员的地盘
class A {
companion object {
fun t(){
println("Tang")
}
}
}
fun main(args: Array<String>) {
A.t()
}
三)作为普通对象使用的伴生对象
Kotlin基础(三)类、对象和接口的更多相关文章
- java面向对象基础(三):对象转型和多态
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- JavaScript 基础(三) - Date对象,RegExp对象,Math对象,Window 对象,History 对象,Location 对象,DOM 节点
Date对象 创建Date对象 //方法1:不指定参数 var date_obj = new Date(); alert(date_obj.toLocaleString()) //方法2:参数为日期字 ...
- ES6基础三(对象)
对象赋值 在es6中,可以直接将声明的变量赋值给对象: Object.keys().Object.values()和Object.entries() 在ES6中,允许我们使用变量作为对象的ke ...
- C# 开发 —— 数组类对象接口
数组类型是从抽象基类 Array 派生的引用类型,通过new运算符创建数组并将数组元素初始化为他们的默认值 一维数组 type[] arrayname; 数组的长度不是声明的一部分,而且数组必须在访问 ...
- java语言基础(八)_接口_多态
接口 1. 接口定义的基本格式 接口就是多个类的公共规范,是一种引用数据类型,最重要的内容就是其中的:抽象方法. 如何定义一个接口的格式: public interface 接口名称 { // 接口内 ...
- JAVA基础学习之流的简述及演示案例、用缓冲区方法buffer读写文件、File类对象的使用、Serializable标记接口(6)
1.流的简述及演示案例输入流和输出流相对于内存设备而言.将外设中的数据读取到内存中:输入将内存的数写入到外设中:输出.字符流的由来:其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表. ...
- IOS基础之 (三) 类的声明和对象的创建
一 OC类的声明和实现语法 1.接口的声明 @interface NewClassName: ParentClassName { 实例变量 ... } 方法的声明 ... @end //...表示省略 ...
- Java基础(三)对象与类
1.类的概念:类是构造对象的模板或蓝图.由类构造对象的过程称为创建类的实例. 2.封装的概念:封装(有时称为数据隐藏)是与对象有关的一个重要概念.对象中的数据称为实例域,操纵数据的过程称为方法.对于每 ...
- [Think In Java]基础拾遗1 - 对象初始化、垃圾回收器、继承、组合、代理、接口、抽象类
目录 第一章 对象导论第二章 一切都是对象第三章 操作符第四章 控制执行流程第五章 初始化与清理第六章 访问权限控制第七章 复用类第九章 接口 第一章 对象导论 1. 对象的数据位于何处? 有两种方式 ...
随机推荐
- 插件使用一进度条---nprogress
nprogress 是像youtube一样在顶部出现进度条,用在一些加载比较缓慢的场景中. 官方网站是 http://ricostacruz.com/nprogress/ 源码在 https://gi ...
- 51 Nod 1242 斐波那契数列的第N项(矩阵快速幂模板题)
1242 斐波那契数列的第N项 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 斐波那契数列的定义如下: F(0) = 0 F(1) = 1 F(n) ...
- OpenCV-Python入门教程6-Otsu阈值法
在说Otsu之前,先说几个概念 灰度直方图:将数字图像中的所有像素,按照灰度值的大小,统计其出现的频率.其实就是每个值(0~255)的像素点个数统计. Otsu算法假设这副图片由前景色和背景色组成,通 ...
- 根据现有的XML文件生成其对应的实体类
方法如下: 1.将完整的Xml文本复制一下, 2.在vs2013(或以上版本) .net4.5项目下建立一个类文件, 3.依次选择菜单:编辑->选择性粘贴->将XML粘贴为类.
- 一键安装基于dns的高可用k8s集群(3节点,etcd https)
在公司,使用dns切换,可能会比keepalived+haproxy,更精简的易维护. 毕竟,高可用只是偶尔切换,不是时时切换. 且dns解析在自己可控时,更不会影响k8s线上使用了. (部分代码,由 ...
- 实战--Keepalived和LVS实现负载高可用
显然,只有上一篇的操作,在WEB运维技术中,只能承担一半的角色. 想像一下,如何LVS本身倒了,肿么办?后端的NGINX再多,也只能是干着急,请求过来不呀! 所以,在本篇时,我们来实现LVS永不倒, ...
- Oracle 11g 安装过程中“检查网络配置要求 未执行”解决方法
正在检查网络配置要求... 检查完成.此次检查的总体结果为: 未执行 网上查了一下,很多朋友都遇到这个问题而无从下手,其实解决起来很容易的. 只需要在 Windows XP 中安装 Microsoft ...
- es6 模板字符串
模板字符串 提供构造字符串的语法糖,在 Prel/python 等语言中也都有类似特性. 1.反引号模板,可以换行 2.反引号模板,可以嵌套 用+``来嵌套 好处:语法更加简洁 var name=&q ...
- 萨塔尼亚的期末考试(fail)
题解: 这题比较妙啊... 首先暴力自己算是找不出规律的 有一种直觉就是可以把式子变成{f[1]+...f[n]}+{f[2]+...+f[n]}+{f[3]+...+f[n]}... 然后看了题解发 ...
- scrapy中输出中文保存中文
1.json文件中文解码: #!/usr/bin/python #coding=utf-8 #author=dahu import json with open('huxiu.json','r') a ...