接口

接口是一个标准

接口是一组方法定义的集合,但是所有方法都没有实现

接口可看做只包含抽象方法的抽象类。

接口天生被用来继承,不能被实例化

语法:public interface 接口名{

          返回值类型方法名(参数列表)

}

一个类如果实现某个接口,就必须实现该接口中定义的所有抽象方法

java规定,子类重写父类的方法,访问控制范围必须大于等于父类的方法

实例:只要标含银联标志的ATM取款机,都可以使用5大银行的银行卡,执行基本操作(以建行、农行为例);然后农行实现手机充值和透支的功能;银联内的银行同时受到监控;然后就是动态实例化和动态调用方法

/*
 * 封装银联标准功能定义的接口
 */
public interface IUnionPay {
	/*
	 * 定义常量备选项w
	 * 完整版 public static final String ABC = "ABC";
	 * public static final会自动添加
	 */
	String ABC = "ABC";//必须声明时初始化
	String CBC = "CBC";
//密码是否验证成功
public abstract boolean checkPwd(String input);
//是否取款成功(public abstract可以省略)
boolean drawMoney(double money);
//返回余额
double getBalance();
//插卡方法的标准定义
void setCard(Card card);
}

public class ATMABC extends ATMCBC implements IABC{
	public boolean drawMoney(double money){
	//如果余额-取款金额>=-2000,说明在透支范围内,允许透支,并返回true
			if ((card.bal-money)>=-2000) {
				card.bal-=money;
				return true;
			}
		return false;	}
	//继承,才能使用其他类的方法,继承ATMCBC使用ATMCBC的三个方法;重写手机充值的方法
public boolean payTelBill(String tel,double money){
如果号码长度是11位,可以充值
//     调用当前的取款方法,取出指定话费
//      如果取款成功,返回true
  if(tel.length()==11){
     if(drawMoney(money)) {
   System.out.println("为"+tel+"号码充值"+money);
     return true;
     }else{
      return false;
 }
    }else{
    return false;
    }}}

/*
 * 封装农业银行标准功能的接口
 */
public interface IABC extends IUnionPay{
//继承了银联的标准接口,自动继承了银联标准接口的所有抽象方法
//子接口中,仅仅需要定义扩展功能即可
 boolean payTelBill(String tel,double money);
}

import java.util.Scanner;

public class InferfaceTest {
	public static void main(String[] args) {
//		ATMCBC atm = new ATMCBC();
//		ATMCBC atm = new ATMCBC();
		Card card = new Card("CBC", "123456", 5000);
//		atm.takPic();
//		atm.setCard(card);
		//第二种方法:使用接口类型变量,引用实现类的对象,实现了动态对象的创建和动态方法的调用
		IUnionPay atm;
		//动态实例化对象
		if(card.bank.equals("CBC")){
			atm = new ATMCBC();
		}else{
			atm = new ATMABC();
		}
		/*
		 * 第二种方法改良版
		 * Card card = new Card(IUnionPay.CBC, "123456", 5000);
		if(card.bank.equals(IUnionPay.CBC)){
			atm = new ATMCBC();
		}else if(card.bank.equals(IUnionPay.ABC)){
			atm = new ATMABC();
		}else{System.out.println("不支持的卡种");
		return;}
		 */
		
		//将银行卡插入atm
		atm.setCard(card);//在父类型IUnionPay中定义标准setCard方法后,此时不再报错
		//atm不能再调用takPic()和setCard方法,因为父类型只能调用子类重写的方法
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入密码");
		String input = sc.next();
		
		//建行atm中三个功能测试:验证、取款、查询余额功能测试
		
		// 调用atm验证密码方法
		// 如果验证通过:
		// 就提示输入取款金额,并保存到money中
		// 调用atm取款方法,判断取款金额:
		// 如果取款成功,提示卡内余额
		// 否则,提示余额不足,取款失败
		// if (atm.checkPwd(input)) {
		// System.out.println("请输入密码");
		// System.out.println("请输入取款金额");
		// double money = sc.nextDouble();
		// if (atm.drawMoney(money)) {
		// System.out.println("取款成功,余额为:"+atm.getBalance());
		// }else{
		// System.out.println("余额不足,取款失败");
		// }
		// }else{
		// System.out.println("验证失败,退出");
		// }
		
		//农行额外的一个功能:充值手机功能测试
		
//		if (atm.checkPwd(input)) {
//			System.out.println("请输入手机号");
//			String tel = sc.next();
//			System.out.println("请输入充值金额");
//			double money = sc.nextDouble();
//			if (atm.payTelBill(tel, money)) {
//				System.out.println("充值成功");
//			} else {
//				System.out.println("余额不足,充值失败");
//			}
//		} else {
//			System.out.println("号码格式不对");
//		}
		
		
		/*
		 * 实现接口中的方法,可以选择继承已有类中已实现的接口中的方法,也可以自己重写,
		 * 比如农行中重写接口中取钱功能,从而实现自己的透支功能;也可以继承建行从而使用建行普通的取款方法
		 */
		
		
		//农行透支功能测试
		
		if (atm.checkPwd(input)) {
			System.out.println("请输入取款金额");
			double money = sc.nextDouble();
		
			if (atm.drawMoney(money)) {
				System.out.println("取款成功,余额为:"+atm.getBalance());
				}else{
				System.out.println("余额不足,取款失败");
				}
	}else{System.out.println("密码验证错误");}
}}
/*
 * 封装建设银行atm功能类
 * 多余atm机类都必须遵守银联中的标准接口
 * 并实现接口中抽象方法
 */
public class ATMCBC implements IUnionPay,IPolice{
   //接口的实现类中,除了实现接口方法外,也可以定义自己专有成员和方法
	public Card card;
	public void setCard(Card card){
		this.card = card;
	}
	//@Override:断言机制,告诉编译器当前方法是重写父类方法,请编译器协助检查方法签名,如果重写的方法签名没在父类中找到,则编译错误
	public boolean checkPwd(String input) {
    //判断输入的input和card对象中的pwd属性是否相同,相同返回true,用equals		
		if (input.equals(card.pwd)) {
			return true;
		}else{
			return false;
		}
	}
	public boolean drawMoney(double money) {
    //先检查card属性bal是否大于等于取款金额,可以true,否则false
		if (card.bal>money) {
			card.bal-=money;
			return true;
		}else{
		return false;}
	}
	public double getBalance() {
		// TODO Auto-generated method stub
		return card.bal ;
	}
	public void takPic() {
		// TODO Auto-generated method stub
		System.out.println("您已经让摄像区域");
	}
}

public class Card {
public String bank;//银行
public String pwd;//密码
public double bal;//余额
public Card(String bank, String pwd, double bal) {
	super();
	this.bank = bank;
	this.pwd = pwd;
	this.bal = bal;
}
}
/*
 * 封装派出所要求功能:每个行的atm都可以拍照
 */
public interface IPolice {
void takPic();
}


动态调用接口方法

接口可以作为一种特殊类型声明一个引用类型的变量
IUnionPay atm;编译正确
一个接口类型的变量可以引用实现了该接口的类的对象;
IUnionPay atm = new ATMCBC();
IUnionPay atm = new ATMABC();
为什么使用接口类型引用实现类的变量呢?因为可以动态调度!
通过接口类型变量仅能调用实现该接口类中重写的方法:

接口和抽象类

相同点

1.天生都是被继承的,都不能实例化;
2.一个类不论是实现接口还是继承抽象类,都必须实现其中所有抽象方法;
3.接口和抽象类都可以声明父类型的变量,引用子类型对象;
4.父类型对象的引用都可以调用子类型对象中重写的方法;

5.因为3,4两条,所以抽象类和接口,都可以实现动态创建对象和动态方法调度;

切记,父类型对象的引用都不能调用子类型对象中非重写的方法

不同点

1.抽象类不允许多继承,而接口可以多继承;
2.使用场景不同:
       -抽象类:主要用于封装子类中共享的成员。只有个别方法自己不能实现,才定义为抽象方法,请子类自力更生;
       -接口:主要用于定义在程序中定义标准。接口完全不是实现任何方法。
3.成员的修饰词不同:
      -抽象类中的成员,可以使用任意关键字修饰;
      -接口中的成员变量都是public stati final ,方法都是public abstract只不过可以省略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值