kotlin抽象类、密封类、接口

1.抽象类

(1)概念

? 从多个具有相同特征的类中抽象出一个使用abstract修饰的类,以这个抽象类作为其子类模板,从而避免子类设计的随意性。抽象类的设计是一种模板模式的设计模式。

(2)特点

  • 抽象类、抽象属性、抽象方法都不需要open修饰符,open修饰符和abstract不能共存。
  • 抽象类不能实例化,但是可以有构造方法,构造方法是给子类用的。
  • 抽象类可以包含:属性(抽象属性或者非抽象属性)、方法(抽象方法或者非抽象方法)、构造器、初始化块、嵌套类(接口、枚举)5中成员。
  • 含有抽象成员(包括直接定义了一个抽象成员、或者继承了一个抽象父类但是没有完全实现父类包含的抽象成员、或者实现了一个接口但没有完全实现接口包含的抽象成员这三种情况)只能被定义为抽象类。
  • abstract不能修饰局部变量。

(3)抽象成员(抽象方法、抽象属性)

? 抽象类里面使用abstract修饰的方法和属性。

  • 抽象方法不能有方法体。
  • 抽象属性不需要初始化。

(4)定义抽象类

下面是抽象类的定义方法

/**
 * 定义一个抽象类
 */
abstract class AbstractClass {
    //抽象属性,不能初始化
    abstract var abstractParam : String
    //抽象方法,不能有方法体
    abstract fun abstractFun()
    //普通属性,子类也可以重写,但是需要open修饰
    var commonParam : Int = 1
    //普通方法,子类也可以重写,但是需要open修饰
    fun commonFun() {
        //方法执行体
    }
    constructor() {
        //构造器,也可以在定义类时定义主构造器,抽象类的构造器是给子类用的,抽象类本身不能实例化
    }
}

下面是子类继承于抽象类的示例

fun main(args: Array<String>) {
    val fruit1 = Orange("橙子")
    val fruit2 = Apple()
    fruit1.eat()
    fruit2.eat()
}

/**
 * 水果抽象类
 */
abstract class Fruit {
    fun eat() {
        println("吃水果:$fruitName ,获取的水果重量${getFruitWeight()}")
    }
    abstract val fruitName : String
    abstract fun getFruitWeight() : Int
}

/**
 * 橘子子类
 */
class Orange(override val fruitName: String) : Fruit() {
    override fun getFruitWeight(): Int {
        return 10
    }
}

/**
 * 苹果子类
 */
class Apple : Fruit() {
    override fun getFruitWeight(): Int {
        return 20
    }

    override val fruitName: String
        get() = "苹果"

}

2.密封类(特殊的抽象类)

(1)概念

? 密封类是一种特殊的抽象类,专门用来派生子类。使用sealed修饰符修饰。

(2)特点

? 密封类的子类是固定的。

原因如下:

  • 密封类的子类必须与密封类在同一个文件。
  • 在其他文件中不能不能为密封类派生子类(但是密封类的子类可以被其他类继承)。

(3)定义密封类

/**
 * 密封类
 */
sealed class SealedClass {
    abstract fun sealedFun()
}

/**
 * 密封类子类1
 */
class SubClass1 : SealedClass() {
    override fun sealedFun() {

    }
}

/**
 * 密封类子类2(使用open修饰,可以在其他文件派生子类)
 */
open class SubClass2 : SealedClass() {
    override fun sealedFun() {

    }
}

3.接口

(1)概念

? 接口定义了系统与外界交互的窗口或者说规范,规定了实现者必须向外界提供哪些服务(方法、属性)。

(2)特点

  • 修饰符:public|internal|private或者省略(省略即是public);
  • 接口只能继承接口,不能继承类;
  • 接口中可以定义抽象/非抽象方法;
  • 接口中可以定义抽象属性/非抽象属性,但是接口中的费抽象属性是没有幕后字段(filed)的,因此需要为之提供get-set方法。
  • kotlin接口中的非抽象成员(方法、属性)可使用public|private两种访问权限修饰(java中自动为接口成员提供public修饰,如果指定访问权限也只能是public),抽象成员只能使用public修饰;
  • 接口不可以包含构造器和初始化块,但接口可包含:方法(抽象方法/非抽象方法)、属性(抽象属性/非抽象属性)、嵌套类(或嵌套接口、嵌套枚举);
  • kotlin接口抽象成员的abstract关键字可以省略(抽象类的抽象成员不能省略);
  • 接口不能实例化,但可以用来声明变量,通过该变量可以赋值给Any(向上转型,因为接口的子类对象一定是Any的子类);
  • 接口的实现类实现该接口的抽象成员只能是public修饰。

(3)定义接口

fun main(args: Array<String>) {
    val person: Human = People("男", 5, 10)
    person.speak()
    (person as? Child)?.howOldAreYou()//向下转型为Child类型
    println("年级:${(person as? Student)?.grade}")//向下转型为Student类型
    val any : Any = person//person可以直接赋给Any
}

/**
 * 定义一个人类接口
 */
interface Human {
    //抽象属性,可省略abstract关键字,var type : String,只能使用public修饰
    abstract var type: String
    //非抽象属性,可以使用public|private访问权限符修饰
    val sex: String
        get() = type

    //非抽象方法,可以使用public|private访问权限符修饰
    fun speak() {
        if (canSpeak()) println("我是${sex}的") else println("不会说话")
    }

    //抽象方法,可省略abstract关键字,fun canSpeak() : Boolean
    abstract fun canSpeak(): Boolean
}

/**
 * 定义一个学生接口
 */
interface Student {
    val grade: Int
}

/**
 * 定义一个小孩抽象类
 */
abstract class Child {
    //抽象类的抽象属性,abstract不能省略
    abstract val age: Int
    //抽象类的费抽象方法(有方法体)
    fun howOldAreYou() {
        println("年龄:$age")
    }
}

/**
 * 定义Person类,继承于Child抽象类,实现了Student接口、Human接口,类后面的抽象类只能有一个,接口可以有多个,摆放顺序随意
 */
class People(override var type: String, override val grade: Int, override val age: Int) : Child(), Student, Human {
    override fun canSpeak(): Boolean {
        return true
    }
}

原文地址:https://www.cnblogs.com/nicolas2019/p/10940504.html

时间: 2024-08-30 17:28:49

kotlin抽象类、密封类、接口的相关文章

抽象类及接口详解

一.前言 在上一节中我们讲到抽象类和接口之间的异同,我们一起回顾下其异同. 同: 1.都不可以被实例化 2.都含有声明但未实现的方法 3.都可以被继承 4.其子类必须实现其声明未实现的方法 异: 1.抽象类是多继承,接口是单继承 2.抽象类可以包含实现的方法,接口不能包含实现的方法 3.接口支持回调,抽象类不支持 4.抽象类更多的定义在一些类关系紧密的类间,接口则定义在实现其某一种功能之间 抽象类和接口的异同我们再次熟悉了一遍,今天我们主要讲的是抽象类和接口使用场景及详讲抽象类的使用方法及接口的

2.35 Java基础总结①抽象②接口③设计抽象类和接口的原则④接口和抽象类的区别

java基础总结①抽象②接口③设计抽象类和接口的原则④接口和抽象类的区别 一.抽象 abstract作用:不能产生对象,充当父类,强制子类正确实现重写方法和类相比仅有的改变是不能产生对象,其他的都有,包括构造.属性等等任何一个类只要有一个抽象的方法就成了抽象类 抽象方法 public abstract A();①方法是抽象的,这个类也是抽象的:②子类必须重写抽象方法,除非子类也是抽象类 抽象类可以没有抽象方法,但一般不这么设计 二.接口 interface 接口也是Java的一种引用数据类型(J

抽象类和接口的区别

含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象.含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的.abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法.如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型. 接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须

Java抽象类与接口的区别

很多常见的面试题都会出诸如抽象类和接口有什么区别,什么情况下会使用抽象类和什么情况你会使用接口这样的问题.本文我们将仔细讨论这些话题. 在讨论它们之间的不同点之前,我们先看看抽象类.接口各自的特性. 抽象类 抽象类是用来捕捉子类的通用特性的 .它不能被实例化,只能被用作子类的超类.抽象类是被用来创建继承层级里子类的模板.以JDK中的GenericServlet为例: public abstract class GenericServlet implements Servlet, ServletC

【翻译】JAVA中抽象类和接口的区别

不知道有没有人翻译过了,这篇是挺简单的,权当复习一遍内容吧. 很多常见的面试问题如"抽象类和接口有什么区别","你在什么时候用抽象类什么时候用接口".所以在这篇文章里面,我们会讨论一下这个话题. 在开始讨论它们的区别之前,我们先看看它们的介绍. Abstract class 抽象类 抽象类被用来抽象出子类的共同特征.它是不能被实例化的,它只能被子类继承作为超类使用.抽象类被用作它的子类下的层次结构创建模板(Abstract classes are used to c

Java重载、覆写、this、super、抽象类、接口

第一.重载和覆写 1) 重载:方法名相同,参数类型和个数不同,典型的是构造方法的重载  覆写:方法名.参数类型.返回值类型全部相同,典型的是接口的实现: 2)重载对权限没有要求:覆写要求  被覆写的方法不能拥有更严格的权限: 3)重载发生再一个类中:覆写发生在继承类中. 第二.this和super 1)this访问本类中的属性(方法),如果本类中没有此属性(方法),则从父类中 继续寻找:super询问父类中的属性(方法): 2)调用本类构造,必须放在构造方法的首行:调用父类构造,必须放在子类构造

关于抽象类和接口

抽象类:含有abstract修饰符的类即为抽象类,它是不能创建实例对象的,含有abstract的方法必须定义在抽象类中,但抽象类中的方法不一定必须是抽象的,抽象类中的抽象方法再其子类中必须被实现,所以不能有抽象的静态方法(静态方法是不能被继承的). 接口:是一个特殊的抽象类,接口中定义的方法都必须是抽象的,接口中的方法都是public abstract类型,接口中的成员变量默认为public abstract final类型. 语法区别:① 抽象类中可以拥有普通的成员变量,接口中没有. ②抽象类

抽象类与接口

接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别. 一.抽象类 我们都知道在面向对象的领域一切都是对象,同时所有的对象都是通过类来描述的,但是并不是所有的类都是来描述对象的.如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样的类我们称它为抽象类.比如new Animal

关于抽象类和接口一些简单的概念

做一下笔记: 1.抽象类可以有构造方法,接口中不能有构造方法.  2.抽象类中可以有普通成员变量,接口中没有普通成员变量  3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法.  4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然  eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型.  5. 抽象类中可以包含静态方法,接口中不能包含静

三、抽象类和接口的对比-----《大话设计模式》

一.抽象类 c#允许把类和方法声明为abstract,即抽象类和抽象方法.抽象类不能实例化,抽象方法必须被子类重写,如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他一般方法. 抽象类拥有尽可能多的共同代码,尽可能少的数据. abstract class Animal //加abstract关键字,表明是抽象类 { -- protected abstract string getShoutSound(); //在方法返回值前加abstract表明此方法是抽象方法. -- //抽象