Java基础系列6: 抽象类和接口
本文是作者的读书笔记和心得整理,部分内容来源于网络,如有侵权,请联系作者。
抽象类
只给出方法的定义而不给出方法体,也就是没有’{}’
包含一个或多个抽象方法的类必须被声明为抽象类
使用abstract修饰符来表示抽象
抽象类不能被实例化,也就是不能new.必须由子类继承实现之后才能实例化子类.
这里还有一个多态的典型例子:
People people=new Teacher("教师");
people.work();
一个核心的判断方法:
抽象类可以不包含抽象方法,包含抽象方法的类就一定是抽象类。
使用抽象类的好处
强调这个方法是必须要实现的,有个提示作用.
接口
接口的意义在于制定标准,往往用于工厂模式.
注意一个实现接口的类,必须实现接口内描述的所有抽象方法
接口内的所有方法都是public abstract的,也可以含有变量,但是也是默认为public static final的,同时接口内的方法是不能再接口内直接实现的.
工厂模式中的接口
工厂模式是为了解耦:把对象的创建和使用的过程分开。就是Class A 想调用 Class B ,那么A只是调用B的方法,而至于B的实例化,就交给工厂类。
其次,工厂模式可以降低代码重复。如果创建对象B的过程都很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。我们可以这些创建对象B的代码放到工厂里统一管理。既减少了重复代码,也方便以后对B的创建过程的修改维护。
由于创建过程都由工厂统一管理,所以发生业务逻辑变化,不需要找到所有需要创建B的地方去逐个修正,只需要在工厂里修改即可,降低维护成本。同理,想把所有调用B的地方改成B的子类C,只需要在对应生产B的工厂中或者工厂的方法中修改其生产的对象为C即可,而不需要找到所有的
new B()改为newC()。
代码引用自:https://how2playlife.com/2019/09/06/6%E6%8A%BD%E8%B1%A1%E7%B1%BB%E5%92%8C%E6%8E%A5%E5%8F%A3/
package demo;
import java.util.Scanner;
interface Fruit //定义一个水果标准
{
public abstract void eat();
}
class Apple implements Fruit
{
public void eat()
{
System.out.println("吃苹果");
}
}
class Orange implements Fruit
{
public void eat()
{
System.out.println("吃橘子");
}
}
class factory
{
public static Fruit getInstance(String className) //返回值是Fruit的子类
{
if("apple".equals(className))
{
return new Apple();
}
else if("orange".equals(className))
{
return new Orange();
}
else
{
return null;
}
}
}
public class ComplexFactory {
public static void main(String[] args)
{
System.out.println("请输入水果的英文名:");
Scanner sc = new Scanner(System.in);
String ans = sc.nextLine();
Fruit f = factory.getInstance(ans); //初始化参数
f.eat();
sc.close();
}
}
接口和抽象类的区别
核心区别:
抽象类表示的是“is a”关系,接口表示的是“like a”关系
接口(interface)和抽象类(abstract class)是支持抽象类定义的两种机制。
接口是公开的,不能有私有的方法或变量,接口中的所有方法都没有方法体,通过关键字interface实现。
抽象类是可以有私有方法或私有变量的,通过把类或者类中的方法声明为abstract来表示一个类是抽象类,被声明为抽象的方法不能包含方法体。子类实现方法必须含有相同的或者更低的访问级别(public->protected->private)。抽象类的子类为父类中所有抽象方法的具体实现,否则也是抽象类。
接口可以被看作是抽象类的变体,接口中所有的方法都是抽象的,可以通过接口来间接的实现多重继承。接口中的成员变量都是static final类型,由于抽象类可以包含部分方法的实现,所以,在一些场合下抽象类比接口更有优势。
相同点
(1)都不能被实例化
(2)接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。
不同点
(1)接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
(2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
(3)接口强调特定功能的实现,而抽象类强调所属关系。
(4)接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。
(5)接口被用于常用的功能,便于日后维护和添加删除,而抽象类更倾向于充当公共类的角色,不适用于日后重新对立面的代码修改。功能需要累积时用抽象类,不需要累积时用接口。