Java接口全解析
来源:互联网 发布:php商城thinkphp 编辑:程序博客网 时间:2024/03/29 18:50
接口:
所有的开发里面可以不使用抽象类,但是没有不使用接口的。
本次讲解知识点:
1.接口的基本概念与主要特点;
2.接口的各个使用;
3.工厂设计模式、代理设计模式。
接口的基本定义:
如果不会接口,其他任何语言都难以理解。
如果一个类之中只是由抽象方法和全局常量所组成,那么不会将其定义为一个抽象类,而只会将其定义为接口,所以严格来讲接口属于一个特殊的类,而且这个类里面只有抽象方法与全局常量。
范例:定义接口
interface A{//定义了接口
public abstract void print();//抽象方法
public static final String MSG = "Hello";//全局常量
}
由于接口里面存在抽象方法,所以接口不能直接使用关键字new进行实例化操作,所以接口的使用原则如下:
1.接口必须有子类,但是此时一个子类可以使用implement关键字实现多个接口
2.接口的子类(如果不是抽象类),必须覆写接口中的全部抽象方法;
3.接口的对象可以利用子类对象的向上转型进行实例化操作。
范例:实现接口:
interface A{//定义了接口
public static fianl String MSG = "Hello";
public abstract void print();//抽象方法
}
interface B{
public abstract void get();
}
class X implements A,B{//X实现了A,B两个接口
public void print(){
System.out.print("A接口的抽象方法");
}
public void get(){
System.out.println("B接口的抽象方法");
}
}
public class TestDemo{
public static void main(String args[]){
X x = new X();//实例化子类对象
A a = x;//向上转型
B b = x;//向上转型
a.print();//调用A接口的print()方法
b.get();//调用B接口的get()方法
}
}
A和B这两个接口没有直接的关系,但是这两个接口却同时拥有一个子类:X子类,千万不要被类型和名称所迷惑。
如果一个子类既要继承抽象类,又要实现接口,那么要先extends抽象类,再写implements接口。
接口的组成仅仅有抽象方法和全局常量。接口中只能使用一种访问权限public。
以下两个代码相同:
interface A{
public static final String MSG = "HELLO";
public abstract void fun();
}
interface A{
String MSG = "HELLO";
void fun();
}
为了防止某些不熟悉语法的开发者出现错误,所以强烈建议在接口定义方法的时候一定要写上public
接口的促成,一般都是以抽象方法为主。
一个抽象可以继承一个抽象类,一个接口可以使用extends同时继承多个接口。但是接口不能继承抽象类。
范例:接口继承多个接口
interface A{
public void funA();
}
interface B{
public void funB();
}
//C接口同时继承了A和B两个父接口
interface C extends A,B{//此处使用的是extends
public void funC();
}
class X implements C{
//此时,X类要覆写3个抽象类
public void funA(){};
public void funB(){};
public void funC(){};
}
从继承关系上讲抽象类的限制比接口多很多:
1.一个抽象类只能继承一个抽象的父类,而接口没有此限制。
2.一个子类只能继承一个抽象类,而接口可以实现多个接口。
在Java中,接口的主要功能是解决单继承局限问题。
尽管所有的接口都是由抽象方法和全局常量组成,但是所有的内部结构不受到这些要求的限制。
所以,在接口里面可以定义普通内部类、抽象内部类、内部接口。
注意:接口中定义抽象方法不用写abstract,而抽象类中定义抽象方法必须写abstract
范例:在接口中定义抽象类
interface A{
public void funA();
abstract class B{//A接口中定义的一个抽象类
public abstract void funB();
}
}
Class X implements A{//X实现了A接口
public void funA(){
System.out.println("覆写A抽象方法");
}
} 类X实现接口A,只需要覆写A抽象方法就行,至于接口A中的抽象类B不用管他,它是一个类文件,与我们无关.
如果想使用接口A中的抽象类B,只需要在X中定义一个内部类Y:
class Y extends B{}//内部抽象类的子类
但是上面的代码一般不会这样写。
范例:在一个接口内部如果使用了static定义一个内部接口,表示是一个外部接口
interface A{
public void funA();
static interface B{//外部接口
public void funB();
}
}
class x implements A.B{//X实现A接口,注意:是A点B
public void funB();
}
总结:接口在实际的开发中,有三大核心作用:
1.定义不同层之间的操作标准
2.表示一种操作的能力
3.表示将服务器的远程方法视图暴露给客户端
接口的实际应用————标准:
范例:定义USB的标准
//标准可以连接不同层的操作类
interface USB{//定义标准一定就是接口
public void start();
public void stop();
}
范例:定义电脑
class Computer{
public void plugin(USB usb){//插入
usb.start();//固定操作
usb.stop();
}
}
范例:定义U盘
class Flash implements USB{
public void start(){
System.out.println("U盘开始使用");
}
public void stop(){
System.out.println("U盘停止使用");
}
}
范例:定义打印机
class Print implements USB{
public void start(){
System.out.println("打印机开始使用");
}
public void stop(){
System.out.println("打印机停止使用");
}
}
public class TestDemo{
public static void main(String args[]){
Computer com = new Computer();
com.plugin(new Flash());
com.plugin(new Print());
}
}
显示生活中,标准的概念随处可见,而在程序里面标准就是用接口来定义的。
接口的应用————工厂设计模式(Factory):
首先观察一段代码:
interface Fruit{
public void eat();
}
class Apple implements Fruit{
public void eat(){
System.out.println("吃苹果");
}
}
public class TestDemo{
public static void main(String args[]){
Fruit f = new Apple();
f.eat();
}
}
此代码不存在语法错误,但问题出现在关键字new上。
确认一个代码真的好的几个标准:
1.客户端调用简单,不需要关注具体的细节
2.客户端之外的代码修改,不影响用户的使用。
新类Orange:
class Orange implements Fruit{
public void eat(){
System.out.println("吃橘子");
}
}
现在的客户端上想要得到这个新的子类对象,需要修改代码,修改为:Fruit f = new Orange();
我们发现,直接在客户端上产生了实例化对象,那么每一次要想更换对象,都需要修改客户端上的执行代码,这样的做法明显是不好的。
在整个代码中,我们只需要关心如何取得一个Fruit对象,之后进行方法的调用,至于这个对象是被谁实例化的,那不是我客户端的工作。
这一类问题就叫做耦合问题,即耦合度太高。耦合的太高会导致代码不方便维护,相当于A一直要与B绑定在一起。
我们可以参考Java虚拟机的设计思想:
程序--》JVM--》适应不同的操作系统
即,开发程序时无需考虑适应不适应操作系统,这写都由JVM解决。
大部分类中如果有static方法,基本上表示这个类中不需要定义属性,或者可能需要取得实例化对象。
增加一个工厂类:
class Factory{
public static Fruit getInstance(String className){
if("apple".equals(className)){
return new Apple();
} else if("orange".equals(className)){
return new Orange();
} else {
return null;
}
}
}
现在的客户端不会看见具体的子类,因为所有的接口对象都是通过Factory类取得的。
面试题:请编写一个Factory程序
接口的应用————代理设计模式(Proxy)
范例:
interface Subject(//整个操作的核心主题
public void make();//整个临幸的核心功能
)
class RealSubject implements Subject{//真是主题(例如皇帝)
public void make(){
System.out.println("皇帝陛下正在XX");
}
}
class ProxySubject implements Subject{//代理主题(例如太监)为真实主题而活
private Subject subject;
//要接收一个真实主题的操作对象
public ProxySubject(Subject subject){
this.subject = subject;
}
public void prepare(){
System.out.println("为临幸做准备!");
}
public void make(){
this.prepare();
this.subject.make();//告诉皇帝可以开始了
this.destroy();
}
public void destroy(){
System.out.println("把娘娘搬走了,皇帝伺候睡觉!");
}
}
public class TestDemo{
public static void main(String args[]){
Subject sub = new ProxySubject(new RealSubject);
sub.make();//调用的是代理主题操作
}
}
代理设计模式的核心精髓在于有一个主题操作接口(里面可能有多种方法),核心业务主题只完成核心功能,例如,吃饭。而代理主题负责完成所有与核心主题有关的操作。
面试题:请编写一个Proxy程序。
无论理解不理解工厂设计模式和代理设计模式,不管用什么方法,一定要把它们背下来。
抽象类和接口的区别(面试题):
抽象类和接口在使用的形式上时非常相似的,所以很多人乐意解释两者的区别:
1.关键字:抽象类是abstract class ,接口是interface
2.组成:抽象类的组成有:构造方法、普通方法、抽象方法、static方法、常量、变量;接口组成有:抽象方法、全局常量。
3.子类使用:抽象类的子类使用是:class 子类 extends 抽象类;接口的子类使用是:class 子类 implements 接口,...,...,..
4.关系:抽象类可以实现多个接口;接口不能继承抽象类,却可以继承多个父接口
5.权限:抽象类可以使用各种权限;接口只能使用public权限。
6.限制:单继承局限;没有单继承局限
7.子类:抽象类和接口都必须有子类,子类必选覆写全部的抽象方法
8.实例化对象:抽象类和接口都依靠子类对象的向上转型进行对象的实例化
比较后发现,抽象类支持的功能比接口更多,但是只有一点不好,就是单继承局限,这一点掩盖了所有抽象类的优点,即:当抽象类和接口都可以使用时,优先考虑接口。
参考:
1.在进行某些公共操作的时候一定要定义出接口。
2.有了接口就需要利用子类完善方法。
3.如果是你们自己写的接口,那么绝对不要使用关键字new直接实例化接口子类,用工厂类完成。
总结:
1.接口与抽象类定义的不同
2.接口作为标准用于解耦合以及不同层之间的连接桥梁
3.一定要将工厂设计模式与代理设计模式的结构记下来
所有的开发里面可以不使用抽象类,但是没有不使用接口的。
本次讲解知识点:
1.接口的基本概念与主要特点;
2.接口的各个使用;
3.工厂设计模式、代理设计模式。
接口的基本定义:
如果不会接口,其他任何语言都难以理解。
如果一个类之中只是由抽象方法和全局常量所组成,那么不会将其定义为一个抽象类,而只会将其定义为接口,所以严格来讲接口属于一个特殊的类,而且这个类里面只有抽象方法与全局常量。
范例:定义接口
interface A{//定义了接口
public abstract void print();//抽象方法
public static final String MSG = "Hello";//全局常量
}
由于接口里面存在抽象方法,所以接口不能直接使用关键字new进行实例化操作,所以接口的使用原则如下:
1.接口必须有子类,但是此时一个子类可以使用implement关键字实现多个接口
2.接口的子类(如果不是抽象类),必须覆写接口中的全部抽象方法;
3.接口的对象可以利用子类对象的向上转型进行实例化操作。
范例:实现接口:
interface A{//定义了接口
public static fianl String MSG = "Hello";
public abstract void print();//抽象方法
}
interface B{
public abstract void get();
}
class X implements A,B{//X实现了A,B两个接口
public void print(){
System.out.print("A接口的抽象方法");
}
public void get(){
System.out.println("B接口的抽象方法");
}
}
public class TestDemo{
public static void main(String args[]){
X x = new X();//实例化子类对象
A a = x;//向上转型
B b = x;//向上转型
a.print();//调用A接口的print()方法
b.get();//调用B接口的get()方法
}
}
A和B这两个接口没有直接的关系,但是这两个接口却同时拥有一个子类:X子类,千万不要被类型和名称所迷惑。
如果一个子类既要继承抽象类,又要实现接口,那么要先extends抽象类,再写implements接口。
接口的组成仅仅有抽象方法和全局常量。接口中只能使用一种访问权限public。
以下两个代码相同:
interface A{
public static final String MSG = "HELLO";
public abstract void fun();
}
interface A{
String MSG = "HELLO";
void fun();
}
为了防止某些不熟悉语法的开发者出现错误,所以强烈建议在接口定义方法的时候一定要写上public
接口的促成,一般都是以抽象方法为主。
一个抽象可以继承一个抽象类,一个接口可以使用extends同时继承多个接口。但是接口不能继承抽象类。
范例:接口继承多个接口
interface A{
public void funA();
}
interface B{
public void funB();
}
//C接口同时继承了A和B两个父接口
interface C extends A,B{//此处使用的是extends
public void funC();
}
class X implements C{
//此时,X类要覆写3个抽象类
public void funA(){};
public void funB(){};
public void funC(){};
}
从继承关系上讲抽象类的限制比接口多很多:
1.一个抽象类只能继承一个抽象的父类,而接口没有此限制。
2.一个子类只能继承一个抽象类,而接口可以实现多个接口。
在Java中,接口的主要功能是解决单继承局限问题。
尽管所有的接口都是由抽象方法和全局常量组成,但是所有的内部结构不受到这些要求的限制。
所以,在接口里面可以定义普通内部类、抽象内部类、内部接口。
注意:接口中定义抽象方法不用写abstract,而抽象类中定义抽象方法必须写abstract
范例:在接口中定义抽象类
interface A{
public void funA();
abstract class B{//A接口中定义的一个抽象类
public abstract void funB();
}
}
Class X implements A{//X实现了A接口
public void funA(){
System.out.println("覆写A抽象方法");
}
} 类X实现接口A,只需要覆写A抽象方法就行,至于接口A中的抽象类B不用管他,它是一个类文件,与我们无关.
如果想使用接口A中的抽象类B,只需要在X中定义一个内部类Y:
class Y extends B{}//内部抽象类的子类
但是上面的代码一般不会这样写。
范例:在一个接口内部如果使用了static定义一个内部接口,表示是一个外部接口
interface A{
public void funA();
static interface B{//外部接口
public void funB();
}
}
class x implements A.B{//X实现A接口,注意:是A点B
public void funB();
}
总结:接口在实际的开发中,有三大核心作用:
1.定义不同层之间的操作标准
2.表示一种操作的能力
3.表示将服务器的远程方法视图暴露给客户端
接口的实际应用————标准:
范例:定义USB的标准
//标准可以连接不同层的操作类
interface USB{//定义标准一定就是接口
public void start();
public void stop();
}
范例:定义电脑
class Computer{
public void plugin(USB usb){//插入
usb.start();//固定操作
usb.stop();
}
}
范例:定义U盘
class Flash implements USB{
public void start(){
System.out.println("U盘开始使用");
}
public void stop(){
System.out.println("U盘停止使用");
}
}
范例:定义打印机
class Print implements USB{
public void start(){
System.out.println("打印机开始使用");
}
public void stop(){
System.out.println("打印机停止使用");
}
}
public class TestDemo{
public static void main(String args[]){
Computer com = new Computer();
com.plugin(new Flash());
com.plugin(new Print());
}
}
显示生活中,标准的概念随处可见,而在程序里面标准就是用接口来定义的。
接口的应用————工厂设计模式(Factory):
首先观察一段代码:
interface Fruit{
public void eat();
}
class Apple implements Fruit{
public void eat(){
System.out.println("吃苹果");
}
}
public class TestDemo{
public static void main(String args[]){
Fruit f = new Apple();
f.eat();
}
}
此代码不存在语法错误,但问题出现在关键字new上。
确认一个代码真的好的几个标准:
1.客户端调用简单,不需要关注具体的细节
2.客户端之外的代码修改,不影响用户的使用。
新类Orange:
class Orange implements Fruit{
public void eat(){
System.out.println("吃橘子");
}
}
现在的客户端上想要得到这个新的子类对象,需要修改代码,修改为:Fruit f = new Orange();
我们发现,直接在客户端上产生了实例化对象,那么每一次要想更换对象,都需要修改客户端上的执行代码,这样的做法明显是不好的。
在整个代码中,我们只需要关心如何取得一个Fruit对象,之后进行方法的调用,至于这个对象是被谁实例化的,那不是我客户端的工作。
这一类问题就叫做耦合问题,即耦合度太高。耦合的太高会导致代码不方便维护,相当于A一直要与B绑定在一起。
我们可以参考Java虚拟机的设计思想:
程序--》JVM--》适应不同的操作系统
即,开发程序时无需考虑适应不适应操作系统,这写都由JVM解决。
大部分类中如果有static方法,基本上表示这个类中不需要定义属性,或者可能需要取得实例化对象。
增加一个工厂类:
class Factory{
public static Fruit getInstance(String className){
if("apple".equals(className)){
return new Apple();
} else if("orange".equals(className)){
return new Orange();
} else {
return null;
}
}
}
现在的客户端不会看见具体的子类,因为所有的接口对象都是通过Factory类取得的。
面试题:请编写一个Factory程序
接口的应用————代理设计模式(Proxy)
范例:
interface Subject(//整个操作的核心主题
public void make();//整个临幸的核心功能
)
class RealSubject implements Subject{//真是主题(例如皇帝)
public void make(){
System.out.println("皇帝陛下正在XX");
}
}
class ProxySubject implements Subject{//代理主题(例如太监)为真实主题而活
private Subject subject;
//要接收一个真实主题的操作对象
public ProxySubject(Subject subject){
this.subject = subject;
}
public void prepare(){
System.out.println("为临幸做准备!");
}
public void make(){
this.prepare();
this.subject.make();//告诉皇帝可以开始了
this.destroy();
}
public void destroy(){
System.out.println("把娘娘搬走了,皇帝伺候睡觉!");
}
}
public class TestDemo{
public static void main(String args[]){
Subject sub = new ProxySubject(new RealSubject);
sub.make();//调用的是代理主题操作
}
}
代理设计模式的核心精髓在于有一个主题操作接口(里面可能有多种方法),核心业务主题只完成核心功能,例如,吃饭。而代理主题负责完成所有与核心主题有关的操作。
面试题:请编写一个Proxy程序。
无论理解不理解工厂设计模式和代理设计模式,不管用什么方法,一定要把它们背下来。
抽象类和接口的区别(面试题):
抽象类和接口在使用的形式上时非常相似的,所以很多人乐意解释两者的区别:
1.关键字:抽象类是abstract class ,接口是interface
2.组成:抽象类的组成有:构造方法、普通方法、抽象方法、static方法、常量、变量;接口组成有:抽象方法、全局常量。
3.子类使用:抽象类的子类使用是:class 子类 extends 抽象类;接口的子类使用是:class 子类 implements 接口,...,...,..
4.关系:抽象类可以实现多个接口;接口不能继承抽象类,却可以继承多个父接口
5.权限:抽象类可以使用各种权限;接口只能使用public权限。
6.限制:单继承局限;没有单继承局限
7.子类:抽象类和接口都必须有子类,子类必选覆写全部的抽象方法
8.实例化对象:抽象类和接口都依靠子类对象的向上转型进行对象的实例化
比较后发现,抽象类支持的功能比接口更多,但是只有一点不好,就是单继承局限,这一点掩盖了所有抽象类的优点,即:当抽象类和接口都可以使用时,优先考虑接口。
参考:
1.在进行某些公共操作的时候一定要定义出接口。
2.有了接口就需要利用子类完善方法。
3.如果是你们自己写的接口,那么绝对不要使用关键字new直接实例化接口子类,用工厂类完成。
总结:
1.接口与抽象类定义的不同
2.接口作为标准用于解耦合以及不同层之间的连接桥梁
3.一定要将工厂设计模式与代理设计模式的结构记下来
阅读全文
1 0
- Java接口全解析
- java事务处理全解析
- java cookie全解析
- Java枚举全解析
- java事务处理全解析
- java事务处理全解析
- java事务处理全解析
- Java层Binder全解析。
- Java日志全解析(上)
- Java日志全解析(上)
- Java日志全解析(下)
- Java抽象类全解析
- java list接口 源码解析
- java.util解析Collection接口
- USB接口的功能和区分全解析
- JAVA String类方法全解析
- Java垃圾回收机制全解析
- 第六届蓝桥杯省赛JAVA-B 全解析
- SQL查询去除汉字保留数字 保留小数
- jQuery-层次选择器
- go语言中的main函数和init函数
- Viewpager+Fragment实现左右滑动切换页面
- 西瓜书《机器学习》课后答案——Chapter3_3.5
- Java接口全解析
- 阿里云上配置数据库卡死
- Spring Eureka的使用与Spring feign的调用
- J
- C快速排序-思想、原理与实现-简笔
- linux my notebook
- java yyyy-MM-dd HH:mm:ss格式的时间存储到MySQL中时 HH:mm:ss显示为00:00:00.000000
- destoon系统标签调用大全
- Hadoop分组统计计算案例