Kotlin自学日记之接口和抽象类的区别(上)

  • 接口 Interface
  • 抽象类 abstract

如何区分接口和抽象类?
以下内容转自:https://www.cnblogs.com/yongjiapei/p/5494894.html
1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2、抽象类要被子类继承,接口要被类实现。
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果
7、抽象类里可以没有抽象方法
8、如果一个类里有抽象方法,那么这个类只能是抽象类
9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
10、接口可继承接口,并可多继承接口,但类只能单根继承。
上述语言描述可能很多人都不能够很好的理解,以下做简单的说明:
抽象类可以理解为:一个事物具有的属性和方法人类具有的属性,性别,年龄,出生年月日,方法,吃喝拉撒睡等等。是描述一个事物固有的属性和动作。
接口可以理解为:一个事物可以实现的功能人类可以学习,可以逛街,可以打游戏等等。

疑问:那么抽象类和接口都可以实现吃饭逛街打豆豆这种行为,他们之间有何区别呢?
答:抽象类是被单根继承的,如果要以子类实例化该抽象类,那么它是单根继承的,也就是说,我不能既是人类又是非人类。但是接口可以被多继承,我可以吃饭逛街打豆豆,但我不影响我是人类。所以在实现某些功能的时候,如果要实现某事物的本质,那么需要用到抽象类,如果实现事物的方法,则使用接口。

对于转载文章所提到的10点,我用代码和一些文字加以说明,来帮助自己理解。

1.抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。

abstract class Human(var name:String)
{	
	fun eat()
	fun drink()  //错误,提示必须要在吃喝方法前加入abstract或者实现上述方法
}

如果定义一个抽象类human,具有吃喝的方法,如果该类是抽象的,那么它的方法也应当是抽象的,也就是说,我知道这是个人,只能知道他可以吃喝,但是不能知道他怎么吃喝。如果要知道怎么吃喝,就得具体到这个人是谁。如果要具体的想知道是谁就要去找到这个人是谁,就需要子类对象去继承该抽象类。
所以

abstract class Human(var name:String)
{	
	abstract fun eat()
	abstract fun drink()
}

此时 子类创建的实例就能知道这个人吃饭和喝水的具体行为是怎样的

class Man:Human(name=String())
{
	override fun eat()
	{
		println("细嚼慢咽")
	}
	override fun drink()
	{
		println("大口喝水")
	}
}

如果我们定义一个接口:

interface eatdinner
{
	fun eatdinner(name:String)
}

这个接口用来实现eatdinner这个行为,但是如果我们不在调用这个接口的类中调用该变量,那么这个接口是无法实例化的。所以需要

class Man:Human(name=String()),eatdinner    //要注意的是继承抽象类需要类名(),方法只需要名字
{
	override fun eat()
	{
		println("细嚼慢咽")
	}
	override fun drink()
	{
		println("大口喝水")
	}
	override fun eatdinner(name:String)
	{
		println("影响均衡的吃")
	}
}

2、抽象类要被子类继承,接口要被类实现。

还是用上面的代码举例子,抽象类定义好了属性和方法,抽象类Human由子类定义并实例化后,人具有这个属性和方法。但是接口在被类中调用后,是实现了某个行为。就好像是,定义出一个人,是人都可以吃喝。但是如果要去进行钓鱼玩游戏这个行为,要某个特殊的人做某个具体动作才行。

3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现

abstract class Human(var name:String)
{	
	fun eat()   //eat就是方法实现
	{
		println("用嘴吃")  
	}
	abstract fun drink()  //drink是方法申明
}

以上例子中,如果用到了方法实现,那么子类继承后是无法进行override的,就好像我定义了吃必须用嘴,但我不能重写一个用耳朵吃饭。

interface eatdinner
{
	fun eatdinner()
	{
		println("自由实现")
	}
}

接口的内部方法可以定义也可以实现,但作用只是用来申明,你可以进行修改也可以不修改。但是抽象类内的方法一旦实现,是不可以进行修改的。

class Man:Human(name=String()),eatdinner    //要注意的是继承抽象类需要类名(),方法只需要名字
{
	override fun drink()  //所以在这里就不需要重写 eat也不能重写eat
	{
		println("大口喝水")
	}
	override fun eatdinner(name:String)
	{
		println("营养均衡的吃")
	}
}
fun main(args: Array<String>) {
    var man1=Man()
    man1.eat()//结果为用嘴吃
    man1.drink()//结果为大口喝水
    man1.eatdinner("11")//结果为营养均衡的吃
}
发布了15 篇原创文章 · 获赞 3 · 访问量 344

猜你喜欢

转载自blog.csdn.net/Py_csdn_/article/details/104666699