构造方法
Kotlin中的类构造方法可以类似java中的编写:
class Rect{
var h:Float;
var w:Float;
constructor(h: Float,w: Float) {
this.h = h
this.w = w
}
}
上述定义了一个矩形类,里面有两个属性(长h、宽w)。constructor为其构造函数的声明关键字。这里要注意的是,在Kotlin中定义属性时需要给该属性赋初值,或者需要一个拥有该属性赋值的构造方法。 否则程序会出错。
也可以这样写:
class Rect(var h: Float,var w: Float){
}
这种写法可以既定义类的属性又声明了构造方法。 关于构造函数详细的写法可以参考:Kotlin中的构造函数
继承
Kotlin中的继承声明为 class 子类名:父类名{}
class Square : Rect(){
}
这里有一个父类Rect,一个子类Square。需要注意的是,父类需要声明open关键字,才可以被子类继承。
open class Rect{
}
在方法的重写上,子类需要声明override关键字来声明此方法为重写父类的方法。相应的父类也需要在对应的方法中声明open关键字
open class Rect{
open fun S(){
}
}
class Square : Rect(){
override fun S(){
}
}
抽象类
Kotlin的抽象类定义与java类似,接下来直接上代码:
abstract class Animal(var name: String){
abstract fun type();
}
class Dog(name: String):Animal(name){
override fun type() {
}
}
使用abstract关键字声明Animal类为一个抽象类,内含一个type的抽象方法。Dog类在继承它的时候自动重写此type方法,并需要加上override的关键字。
接口定义与继承
Kotlin的接口定义和继承与java写法大致,以下是子类继承了父类和一个接口的例子:
abstract class Animal(var name: String){
abstract fun type();
}
interface Ability{
fun shout();
}
class Dog(name: String):Animal(name),Ability{
override fun shout() {
}
override fun type() {
}
}
is关键字
在java的多态中我们可以使用一个父类的对象通过instanceof关键字来判断其是否为某个子类的引用。而类似的在Kotlin里也可以使用is关键字来进行判断。
fun main(args: Array<String>) {
var a: Animal = Dog("Boby");
if(a is Dog){
println(a.name);
}
}
输出结果:
Boby
代理与委托
Kotlin可以使用by关键字实现代理模式,详情可见:kotlin 委托
单例
Kotlin可以利用object关键字声明一个类为单例模式。
object SignalInstance{
}
我们可以试着定义两个变量都为SignalInstance的。
var b = SignalInstance;
var c = SignalInstance;
println(b == c);
输出结果:
true
枚举型
Kotlin中通过enum class 关键字定义一个枚举型。如:
enum class NUMBER{
ONE,TWO,THREE,FOUR,FIVE
}
通过类名.属性的格式可以获取该属性:
println(NUMBER.ONE);
输出结果:
ONE
可通过ordinal关键字获取此属性在枚举中的位置:
println(NUMBER.ONE.ordinal);
输出结果:
0
印章类
sealed关键字可以定义一个印章类,印章类让一个类拥有了有限多个子类。印章类甚至可以理解为一个特殊的枚举类。印章类本身不能被实例化。
sealed class Option(var num1:Int,var num2:Int){
class add(num1: Int,num2: Int):Option(num1,num2){
fun add() = num1+num2;
}
class sub(num1: Int,num2: Int):Option(num1,num2){
fun sub() = num1-num2;
}
}
在main函数中定义如下变量会出错:
var x : Option = Option(1,1);
这是因为Option类为印章类,其本身不可被实例化。
以下是一段使用印章类的代码:
fun main(args: Array<String>) {
var a : Option = Option.Add(2,3);
var b : Option = Option.Sub(3,2);
var list = listOf<Option>(a,b);
for (o in list){
if(o is Option.add){
println(o.add());
}else if(o is Option.sub){
println(o.sub());
}
}
}
上述通过定义在Option的印章类中两个子类的对象,在通过调用其子类中的不通方法完成输出。 印章类可定义有限的子类,每个子类中都有其自定义的内容,这是与枚举相比的最大区别。