标签:message 开发 void 建议 ade rgs ring 还需要 contain
@
接口是一组常量和抽象方法的集合,在Java中国你接口可以使用interface
关键字来定义。
范例:定义一个接口
interface IMessage { // 接口标识头加个I,便于区分
public static final String MSG = "这是一个全局常量MSG" ; // static全局,final常量
public abstract void print() ; // 一个抽象方法,没有方法体
}
如果子类想要使用接口,就必须用到关键字implements
来实现接口。
同时一个子类可以实现多个接口,也就是说可以利用接口来实现多继承的概念。
范例:接口实现多继承
interface IMessage { // 接口标识头加个I,便于区分
public static final String MSG = "这是一个全局常量MSG" ; // static全局,final常量
public abstract void print() ; // 一个抽象方法,没有方法体
}
interface INews {
public abstract String get() ;
}
// 一个子类可以同时实现多个接口
class MessageImp implements IMessage,INews {
public void print() {
System.out.println(IMessage.MSG) ;
}
public String get() {
return IMessage.MSG ; // 访问常量建议加上类名称
}
}
public class TestDemo {
public static void main(String args[]) {
IMessage msg = new MessageImp() ; // 子类为父接口实例化
msg.print() ; // 调用被子类覆写过的print()方法
}
}
既然子类继承了两个接口,那么当然也可以:
public class TestDemo {
public static void main(String args[]) {
INews news = new MessageImp() ; // 子类为父接口实例化
System.out.println(news.get()) ; // 调用被子类覆写过的get()方法
}
}
回顾:《阿里云【名师课堂】Java面向对象开发64:多态性》中的对象多态性概念。
······
public class TestDemo {
public static void main(String args[]) {
INews n = new MessageImp() ; // 子类为父接口实例化
System.out.println("【INews】" + n.get()) ; // 调用被子类覆写的INews中的get()方法
// 重点在关键字new,n被实例化为MessageImp的对象
// 并且MessageImp是IMessage的子类
IMessage msg = (IMessage)n ; // 转型为IMessage的对象
msg.print() ; // 调用被覆写的IMessage中的方法
}
}
分析:
当一个子类继承了多个接口之后,并且接口对象通过子类进行实例化,那么这个对象在多个父接口之间是允许互相转换的。
首先需要说明:接口中只允许存在public
权限。也就是说,不管是属性还是方法,其权限都是public
。
abstract
修饰,给出方法体,而且方法的访问权限一定要用public
来修饰(否则就降低了权限)。abstract
可以省略,因为没有abstract
它也是抽象方法。当一个子类既需要实现接口又需要继承抽象类的时候,请先使用extends
继承抽象类,而后再使用implements
实现接口。
范例:让子类继承抽象类和实现接口
interface IMessage { // 接口标识头加个I,便于区分
public String get() ; // 一个抽象方法,没有方法体,在接口中省略了abstract
}
abstract class AbstractMessage { // 抽象类标识头加个Abstract,便于辨识
public abstract void print() ; // 一个抽象方法,没有方法体
}
class MessageImpl extends AbstractMessage implements IMessage { // 接口的子类标识末尾加上Impl
public String get() {
return "覆写接口的方法" ;
}
public void print() { // 去abstract、加方法体
System.out.println("覆写抽象类方法") ;
}
}
public class TestDemo {
public static void main(String args[]) {
IMessage msg = new MessageImpl() ;
System.out.println(msg.get()) ;
// MessageImpl是抽象类和接口的共同子类,可以转型
AbstractMessage amsg = (AbstractMessage)msg ;
amsg.print() ;
}
}
一个抽象类可以使用implements
实现多个接口,但是接口不能够去继承抽象类。
interface IMessage {······}
abstract class AbstractMessage implements IMessage { // 抽象类实现接口
public abstract void print() ; // 本身就是抽象类,无需再覆写接口中的抽象方法
}
class MessageImpl extends AbstractMessage { // 通过继承实现接口的抽象类,子类也实现了接口
public String get() {
return "覆写接口的方法" ;
}
public void print() { // 去abstract、加方法体
System.out.println("覆写抽象类方法") ;
}
}
public class TestDemo {······}
可以看到与上一个程序达到完全相同的效果。
实际上,这段结构被称为三重继承。
范例:观察“假实现”
interface IMessage {
public String get() ;
public void print() ;
}
abstract class AbstractMessage implements IMessage {
public void print() { // 重载IMessage中的print抽象方法
System.out.println("假实现,抽象类覆写接口的print方法") ;
}
}
/*
class MessageImpl extends AbstractMessage implements IMessage {}
这时如果按这句写,起到的作用是强调MessageImpl是IMEssafe的子类
但是这只是一个重复标记,功能与直接写 class MessageImpl extends AbstractMessage {}完全一致
*/
class MessageImpl extends AbstractMessage {
public String get() {
return "子类覆写接口的get方法" ;
}
}
public class TestDemo {······}
可以看到,print方法被抽象类实现了,get方法被子类实现了。
下面进行正常三重继承
与假实现
流程分析:
这种加重结构描述的方法用于比较多的抽象类与方法的实现时,方便使用者捋清关系、看懂程序。
虽然接口不可以继承抽象类,但是一个接口可以使用extends
关键字来继承多个父接口。
interface A {
public void printA() ;
}
interface B {
public void printB() ;
}
interface C extends A,B {
public void printC() ;
}
class Impl implements C {
public void printA() {}
public void printB() {}
public void printC() {}
}
public class TestDemo {
public static void main(String args[]) {
}
}
接口可以定义一系列的内部结构,包括:内部普通类、内部抽象类、内部接口。其中,使用static定义的内部就扣就相当于外部接口。
interface A {
static interface B { // 使用了static定义,描述一个外部接口
public void printB() ;
}
}
class X implements A.B { // 实现内部接口
public void printB() {}; // 覆写接口中的抽象方法
}
public class TestDemo {
public static void main(String args[]) {
}
}
与抽象类相同,这种内部接口的方法仍然不是编程时的首选。
对于接口在实际的开发之中有三大核心应用环境:
现在描述一个概念:要求电脑上可以使用任何的USB设备。
interface USB { // 忘了写IUSB,doesn‘t matter
public void setUp() ; // 定义:需要先安装驱动
public void operation() ; // 定义:正常工作
}
class Computer { // 电脑只负责提供接口,不关心是哪些设备插入
public void plugin(USB usb) { // 只能插入USB设备
usb.setUp () ; // 所有设备都要安装驱动
usb.operation () ; // 所有设备都要正常工作
}
}
class USBFlashDisk implements USB {
public void setUp() {
System.out.println("成功安装U盘驱动!") ;
}
public void operation() {
System.out.println("进行数据传输!") ;
}
}
class Printer implements USB {
public void setUp() {
System.out.println("成功安装打印机驱动!") ;
}
public void operation() {
System.out.println("进行文档打印!") ;
}
}
public class TestDemo {
public static void main(String args[]) {
Computer pc = new Computer() ;
/* USBFlashDisk udisk = new USBFlashDisk() ;
Printer pri = new Printer() ;
pc.plugin(udisk) ;
pc.plugin(pri) ; */
pc.plugin(new USBFlashDisk()) ;
pc.plugin(new Printer()) ;
}
}
把上述代码结合,成果满足要求:
通过这段程序,我们可以发现使用接口和对象多态性的概念结合之后,对于参数的统一更加明确了。
而且可以发现,接口是在类之上的设计抽象。
区别 | 抽象类 | 接口 |
---|---|---|
关键字 | abstract class 类名称 {} |
interface 接口名称 {} |
结构组成 | 抽象方法、普通方法、全局变量、全局常量、属性、构造方法 | 抽象方法、全局常量 |
权限 | 各种权限(理论上) | 只有public访问权限 |
子类定义 | extends 继承抽象类 |
implements 实现接口 |
关系 | 一个抽象类可以实现若干个接口 | 一个接口不能继承抽象类,但是可以使用extends 继承多个父接口 |
子类限制 | 一个子类只能继承一个抽象类(单继承) | 一个子类可以实现多个接口(多继承) |
联系:抽象类和接口都可以有抽象方法,都不能被实例化,都是引用数据类型。
接口与抽象类的选择:
我们已经学习的结构体:类、对象、抽象类、接口之间的关系可以用一张图描述:
阿里云【名师课堂】Java面向对象开发68 ~ 70、73:接口的定义和使用
标签:message 开发 void 建议 ade rgs ring 还需要 contain
原文地址:https://www.cnblogs.com/playerone/p/13162001.html