目录
1.接口的理解和定义
2.接口实现数据回调
3.接口实现回调(中介租房)
4.接口补充:对象引用
1.接口的理解的定义
使用interface表示定义一个接口
接口也可以继承多个接口(多个接口之间用逗号隔开)
接口内部元素
1.接口不能被实例化(没有构造方法)
2.定义变量(只能是静态成员变量)(默认修饰符public static final)
3.方法
- 抽象方法(常用):不需要自己实现。谁用谁就实现(默认修饰符public abstract)
- 使用implements实现接口
- 必须实现接口里面定义的方法
- 类方法、默认方法、私有方法:可以实现
4.内部接口
一个Demo让大家了解接口的定义和基本使用:
Step1.定义一个数据接口类:DataInteraction,并创建输出和输入方法
public interface DataInteraction {
interface Input{
void input();
}
interface Output{
void output();
}
}
Step2.创建三个子类分别实行数据接口的方法(可自由挑选方法)
//Macbook的实行方法
public class Macbook implements DataInteraction.Input {
@Override
public void input() {
System.out.println("电脑接收到数据");
}
public void printf(){
System.out.println("电脑输出数据");
}
}
//打印机的实行方法
public class Printer implements DataInteraction.Input,DataInteraction.Output{
@Override
public void input() {
System.out.println("打印机从电脑得到数据");
}
@Override
public void output() {
System.out.println("打印机开始打印");
}
}
//鼠标的实行方法
public class Mouse implements DataInteraction.Output{
@Override
public void output() {
System.out.println("鼠标输入坐标位置:东经38 北纬20");
}
}
我们可以看到:在数据接口类中可以定义内部类,后续的实行中就可以自由选择需要的接口,接口之间用逗号隔开
2.接口实现数据回调
我们直接做一个图片下载请求Demo来看看具体的接口使用吧:
实现过程:
1.定义一个接口 统一返回数据的方式;
2.定义一个变量接收谁来监听网络下载完毕的事件;
3.任务结束 回调数据;
4.提供set方法保存当前的监听者;
5.必须实现接口内部的的所有抽象方法;
6.必须传递当前对象给功能类;
7.调用功能类 完成功能;
public class Http {
//1.定义一个接口 统一返回数据的方式
public interface OnHttpFinishListener{
void onSuccess(String img);
void onFailure(String err);
}
//2.定义一个变量接收谁来监听网络下载完毕的事件
private OnHttpFinishListener listener;
public void getData(String url){
System.out.println("开始下载...");
System.out.println("图片下载完毕...");
//3.任务结束 回调数据
listener.onSuccess("张柏芝和冠希哥的图片下载成功");
}
//4.提供set方法保存当前的监听者
public void setListener(OnHttpFinishListener listener){
this.listener = listener;
}
}
第二个类来实行方法的调用:
//使用者必须实现这个接口
public class SplashView implements Http.OnHttpFinishListener {
public SplashView(){
//开始下载数据
Http http = new Http();
//6.必须传递当前对象给功能类
http.setListener(this);
//7.调用功能类 完成功能
http.getData("www.baidu.com");
}
//5.必须实现接口内部的的所有抽象方法
@Override
public void onSuccess(String img) {
System.out.println("展示图片:" + img);
}
@Override
public void onFailure(String err) {
System.out.println("下载失败:" + err);
}
}
最后在MyClass中运行:
public class MyClass {
public static void main(String[] args) {
SplashView sv = new SplashView();
}
}
运行结果:开始下载...
图片下载完毕...
展示图片:张柏芝和冠希哥的图片下载成功
3.接口实现回调(中介租房)
Method1.callback_normal
Step1.定义一个中介类
public class Agent {
private Person fupo;
private Dog keji;
private Cat mCat;
public void rentHouse(){
System.out.println("我是中介:开始找房源");
System.out.println("房子找到了!");
//返回数据
if (fupo != null){
fupo.callBackUseQQ("你好");
}
if (keji != null){
keji.callBackUsePhone();
}
if (mCat != null){
mCat.callBackUseMsn();
}
}
public void setFupo(Person fupo){
this.fupo = fupo;
}
public void setKeji(Dog keji){
this.keji = keji;
}
public void setmCat(Cat mCat){
this.mCat = mCat;
}
}
Step2.分别定义三个不同用户的请求和回应
//Person类
public class Person {
public void needOneHouse(){
//找一个中介 完成租房功能
Agent agent = new Agent();
//告诉他是谁让他做到(告诉他有结果了返回给谁)
agent.setFupo(this);
//开始找房
agent.rentHouse();
}
//自己定义一个接收的方法
public void callBackUseQQ(String mag){
System.out.println("辛苦了");
}
}
//Dog类
public class Dog {
public void wangwang(){
//找中介
Agent zs = new Agent();
//告诉他结果返回给谁(谁接收返回的数据)
zs.setKeji(this);
//开始找房
zs.rentHouse();
}
public void callBackUsePhone(){
System.out.println("wangwangwang");
}
}
//Cat类
public class Cat {
public void miaomaio(){
//找一个中介 完成租房功能
Agent agent = new Agent();
//告诉他是谁让他做的(告诉他有结果了返回给谁)
agent.setmCat(this);
//开始找房
agent.rentHouse();
}
public void callBackUseMsn(){
System.out.println("maiomiao");
}
}
很明显的看到:这种定义方法十分繁琐而且没有必要
对功能类来说:
1.每增加一个使用者,需要添加一个成员变量保存;
- 解决办法:使用多态,用接口类型的变量,接收所有子类类型
2.写一个set方法设置对象;
3.判断并且调用这个对象的相应方法接收数据;
对使用者来说:
1.必须自己来定义一个方法类接收数据
- 解决办法:定义接口,接口中规范接收的方式
为了解决以上问题,我们采用第二种方法:
Method2.callback_interface
Step1.定义一个中介类
public class Agent {
private OnAgentFinishListener listener;
public void setListener(OnAgentFinishListener listener) {
this.listener = listener;
}
public void rentHouse(){
System.out.println("我是中介:开始找房源");
System.out.println("房子找到了!");
//回调数据
if (listener != null){
listener.onFinish("四合院");
}
}
public interface OnAgentFinishListener{
void onFinish(String des);
}
}
Step2.分别定义两个不同用户的请求和回应
//Person类
public class Person implements Agent.OnAgentFinishListener{
public void needOneHouse(){
Agent xw = new Agent();
xw.setListener(this);
xw.rentHouse();
}
@Override
public void onFinish(String des) {
System.out.println("我是pxd 喜欢你的房子:" + des);
}
}
//Dog类
public class Dog implements Agent.OnAgentFinishListener{
public void wangwang(){
Agent xw = new Agent();
xw.setListener(this);
xw.rentHouse();
}
@Override
public void onFinish(String des) {
System.out.println("我是旺财 房子太大了:四合院");
}
}
这里我们使用接口对用户的回应方式定了规范,让代码更简洁,用户也不用自己定义回应方法,直接实行父类提供发的接口就行了
4.接口补充:对象引用
多态只能子类向父类转
接口可视为特殊的父类
class Father implements Communicate{
}
abstract class Cute{
}
interface Communicate{
//接口无法实例化
}
class Child extends Father implements Communicate{
}
/**
* 多态只能子类向父类转
*/
public class MyClass {
public static void main(String[] args) {
Child a = new Child();
Father b = new Father();
test1(a);
test2(b);
test3(a);
}
public static void test1(Child a){
//使用的时候还是要转化为子类的对象 为了让接口更统一
System.out.println("孩子是父亲的孩子");
}
public static void test2(Father b){
System.out.println("父亲");
}
public static void test3(Communicate a){
System.out.println("跟孩子交流");
}
}
总结
1.接口就是一套行为规范,有了接口,我们能在一套规范里面做事儿,免去繁琐的自行创建步骤;
2.既然接口做到了规范一致性,我们就要为这个规范提供高质量的服务(丰富的方法,使用的操作),使使用接口的价值更大!