抽象类和接口其实在使用上基本类似,接口的出现也是为了弥补抽象类的不足。
在类的继承中,有一种“is-a“的关系,子类是一种父类。但是在某些情况下,抽象类的使用虽然在编译上没有问题,但是在逻辑上会出现问题。
比如我想要列举会游泳的东西,我首先会想到鱼,那么我可以让鱼作为父类,定义一个抽象的方法游泳,然后列举具体的鱼去继承鱼这个父类。后来我想到人也可能会游泳,那么我让人去继承鱼这个父类,这虽然在编译上没有任何问题,但是在逻辑上会觉得很奇怪,“人是一种鱼?“。因此需要接口来解决这个问题。
接口可以用于定义行为但不定义操作,即我可以定义这个接口中有swim()这个行为,但没有具体的方法体(类似抽象类中的抽象方法)。所有会游泳的东西都可以去实现这个行为,表示会游泳。
通过接口,就避免了在抽象类中“is-a“逻辑上的错误。
以Java的语意来说,继承会有“是一种“关系,操作接口则表示“拥有行为“,但不会有“是一种“但关系。