什么是接口?
接口定义:接口是一个抽象方法与全局常量(static final是全局常量)的集合。
为什么要有接口?
抽象类与普通类相比最大的特点是约定了子类的实现要求,但是抽象类存在单继承局限。如果要约定子类的实现要求并避免单继承局限就需要使用接口。接口可以实现多继承即一个子类可以继承多个接口。
接口优先原则:在一个操作中既可以使用抽象类又可以使用接口的时候,优先考虑使用接口。(抽象类必须有is -a关系,接口没有is-a关系)
接口使用interface关键字定义;
接口的命名规范:接口前加I 来区分接口与类。
子类实现接口使用implements关键字,并且子类可以同时实现多个父接口(可以使用接口实现多继承),一般使用接口名+Impl来命名子类。
定义一个简单的接口:
interface IA //IA是一个接口,为了区别类在接口前加I
{
abstract public void func(); //抽象方法
static final int a=10; //全局常量,必须在声明时初始化,因为用final声明
}
子类实现接口和父接口之间的相互转化:
interface IA //IA是一个接口,为了区别类在接口前加I
{
abstract public void func1(); //抽象方法
static final int a=10; //全局常量,必须在声明时初始化,因为用final声明
}
interface IB
{
abstract public void func2(); //抽象方法
}
class AImpl implements IA ,IB
{
public void func1() //覆写func1()
{
System.out.println("子类实现接口IA");
}
public void func2() //覆写func2()
{
System.out.println("子类实现接口IB");
}
}
public class Interface1
{
public static void main(String[] args)
{
IA a1=new AImpl(); //向上转型,为父接口实例化对象
a1.func1(); //调用子类覆写的func1() ->子类实现接口IA
IB b1=(IB)a1; //父接口之间的相互转化,a1是通过子类AImpl new出来的
b1.func2(); //调用子类覆写的func2() ->子类实现接口IB
}
}
为什么可以实现父接口的相互转化?
因为父类都是子类new出来的,只要看new 在哪儿即可,不用看期间的各种类名。
接口使用限制:
- 接口中只有public 权限(不管是属性还是方法,其权限均是public),所以可以将权限public省略。另外接口中public static final abstract均可以省略(因为抽象类只有抽象方法和全局常量,那么不写就会这样默认)
阿里编码规约:接口中的属性和方法不要加任何修饰符,public也不要加,保证代码简洁性。 - 当一个子类既需要实现接口又需要继承抽象类时,要先使用extends继承一个抽象类,而后保证implements实现多个接口。(因为不知道接口有多少个,而继承只有一个)
同样,父接口和父类之间可以实现相互转化:
interface IA //IA是一个接口,为了区别类在接口前加I
{
void func1(); // 默认为抽象方法
int a=10; //默认全局常量,
}
interface IB
{
void func2(); //抽象方法
}
abstract class C
{
abstract public void func3();
}
class ABCImpl extends C implements IA,IB //继承了抽象类,2个接口
{
public void func3()
{
System.out.println("子类实现抽象类C");
}
public void func2()
{
System.out.println("子类实现接口IB");
}
public void func1()
{
System.out.println("子类实现接口IA");
}
}
public class Interface1 //主类
{
public static void main(String[] args)
{
IA a1=new ABCImpl(); //向上转型,为父接口实例化对象
a1.func1(); //调用子类覆写的func1() ->子类实现接口IA
IB b1=(IB)a1; //父接口之间的相互转化,a1是通过子类AImpl new出来的
b1.func2(); //调用子类覆写的func2() ->子类实现接口IB
C c1=(C)b1;
c1.func3(); // 父接口和父类之间的相互专户 ->子类实现抽象类C
}
}
- 抽象类可以用implements实现接口,但是接口不能用extends继承抽象类(因为接口中只有抽象方法和全局常量,而抽象类中不止只有抽象方法,还有普通方法…)
/////抽象类实现(interface)接口
interface IA
{
void func1();
}
abstract class AImpl implements IA //AImpl是抽象类,抽象类可以不覆写接口中的抽象方法
{
abstract public void func2(); //抽象方法,而且abstract不可省略,否则是普通方法
}
class A extends AImpl
{
public void func1()
{
System.out.println("抽象类interface接口");
}
public void func2()
{
System.out.println("子类实现抽象类抽象方法");
}
}
public class Interface1
{
public static void main(String[] args)
{
IA a=new A();
a.func1(); //抽象类interface接口
//A是接口IA和抽象类AImpl的共同子类
AImpl ai=(AImpl)a;
ai.func2(); //子类实现抽象类抽象方法
}
}
- 接口可以使用extends继承多个父接口。
/////一个接口继承多个接口
interface IA
{
void func1();
}
interface IB
{
void func2();
}
interface IC extends IA,IB
{
void func3();
}
class ABCImpl implements IC
{
public void func1()
{
System.out.println("接口C继承接口A");
}
public void func2()
{
System.out.println("接口C继承接口B");
}
public void func3()
{
System.out.println("接口C");
}
}
public class Interface1
{
public static void main(String[] args)
{
IC c=new ABCImpl(); //向上转型
c.func3(); //接口C
IA a=(IA)c;
a.func1(); //接口C继承接口A
IB b=(IB)a;
b.func2(); //接口C继承接口A
IA a2=new ABCImpl();
a2.func1(); //接口C继承接口A
IB b2=(IB)a2;
b2.func2(); //接口C继承接口A
IC c2=(IC)b2;
c2.func3(); //接口C
//上面例子更加印证了是否可以强转或者转换,主要看new 后面的对象。
}
}
接口作用:
- 定义操作标准
- 表示一种能力,进行一项操作
- 在分布式开发中暴露远程服务方法
接下来,主要介绍接口标准化,通过电脑的接口和停车场停车两个例子进行结合:
首先是电脑接口:
////电脑有接口,而接口都是一样的,只是接口类别不同,那么就可以利用接口统一化,完成一些操作
interface IUsb //定义一个Usb接口
{
void setUp(); //安装
void work(); //工作
}
class Computer //电脑类
{
public void plugin(IUsb usb) //用接口实现标准化,通过向上转型
{
usb.setUp();
usb.work();
}
}
class printUsbImpl implements IUsb
{
public void setUp()
{
System.out.println("安装打印机");
}
public void work()
{
System.out.println("打印机工作");
}
}
class uDiskImpl implements IUsb
{
public void setUp()
{
System.out.println("安装U盘");
}
public void work()
{
System.out.println("U盘工作");
}
}
public class InterStander
{
public static void main(String[] args)
{
Computer computer=new Computer();
computer.plugin(new printUsbImpl()); //安装打印机 打印机工作
computer.plugin((new uDiskImpl())); //安装U盘 U盘工作
}
}
接下来是停车场停车:停车场停车,但车有很多种,可以将车定义为一个接口,停车场是一个类,再根据不同类型的车实现接口:
////停车场停车
interface Ivehicle //定义一个车的接口
{
void kind(); //车的类型 假设只有一个抽象方法
}
class Park
{
public void whoPark(Ivehicle vehicle)
{
vehicle.kind();
}
}
class AutiImple implements Ivehicle
{
public void kind()
{
System.out.println("奥迪在停车");
}
}
class BenzImpl implements Ivehicle
{
public void kind()
{
System.out.println("奔驰在停车");
}
}
public class InterStander
{
public static void main(String[] args)
{
Park park=new Park();
park.whoPark(new AutiImple()); //奥迪在停车
park.whoPark((new BenzImpl())); //奔驰在停车
}
}