接口和抽象类的区别
- 将公共的属性和行为抽到父类中
所有子类行为都一样—普通方法 - 所有子类行为都不一样—抽象方法
- 符合既是也是的情况使用接口(部分子类有共同行为,而不是所有子类有共同行为)
- 一个类只能继承一个抽象类,但是可以实现多个接口
- 抽象类中可以包含抽象方法和普通方法,而接口中的所有方法均为抽象的
多态
多态的意义
- 同一类型引用指向不同对象时,有不同的实现
- 同一个对象被造型为不同的类型时,有不同的功能
向上造型
- 父类的引用指向子类的对象
- 能造型为的类型有:父类+实现的接口
- 能点出什么来,看引用类型
强制类型转换
- 引用所指向的对象,就是该类型
- 引用所指向的对象,实现了该接口
instanceof
- 作用:判断引用指向的对象,是否是该类型
- 返回rue和false,强转成功的条件就是它为true的条件
- 建议:强转之前先通过instenceof判断后,再强转
内部类
成员内部类
- 类中套类,里边的叫内部类(Inner),外边的叫外部类(Outer)
- 内部类通常只服务于外部类,对外不可见
- 内部类对象通常在外部类中创建
- 内部类中可以直接访问外部类的成员
内部类中默认一个隐式的引用指向外部类
匿名内部类
- 若需要创建一个类(子类)的对象,并且对象只创建一次,则该类不必命名,称之为匿名内部类
- 匿名内部类中访问外部的变量,该变量必须是final的
案例
“银行卡系统(实现银联接口) (上一章博客的案例)”基础上实现本案例,本案例要求实现中国农业银行的ATM系统,详细要求如
1. 中国农业银行的ATM机对所有银联卡提供检查密码功能、取款功能以及查询余额功能。
2. 如果为农行的卡,可以实现支付电话费功能。
import java.util.Scanner;
public class ATMTest {
public static void main(String[] args) {
ABCATM atm=new ABCATM();
UnionPay abc=new ABCImpl(3000,1603);
atm.insertCard(abc);
atm.allMenu();
}
}
//农行ATM
class ABCATM{
UnionPay card;
Scanner sc=new Scanner(System.in);
public void insertCard(UnionPay card){
this.card=card;
}
public void outCard(){
card=null;
}
public void showBalance(){ //显示余额
System.out.println("卡内余额:"+card.getBalance());
}
public void takeMoney(){ //取钱
System.out.println("请输入取钱金额:");
double number=sc.nextDouble();
if(card.drawMoney(number)){
System.out.println("取款成功!");
}else{
System.out.println("取款失败!");
}
}
public void payTelBill(){ //电话缴费
if(card instanceof ABCImpl){
ABCImpl abccard=(ABCImpl)card;
System.out.println("请输入电话号码:");
String phoneNum=sc.next();
while(phoneNum.length()!=11){
System.out.println("请输入电话号码:");
phoneNum=sc.next();
}
if(phoneNum.length()==11){
System.out.println("请输入缴费金额:");
double calls=sc.nextDouble();
if(abccard.payTel(phoneNum,calls)){
System.out.println("缴费成功!");
}else{
System.out.println("缴费失败!");
}
}else{
System.out.println("您输入的电话号码有误!");
}
}else{
System.out.println("您的银行卡非农行卡,不支持电话缴费");
}
}
public void allMenu(){ //功能菜单
do{
System.out.println("请输入密码:");
int input=sc.nextInt();
if(card.checkPwd(input)){
System.out.println("请选择功能:1.查询余额 2.电话缴费 3.取款 0.退出");
int a=sc.nextInt();
if(a==0){
System.out.println("退出系统!");
break;
}else{
switch(a){
case 1:showBalance();
break;
case 2:payTelBill();
break;
case 3:takeMoney();
break;
default:System.out.println("非法输入!");
}
}
break;
}else{
System.out.println("密码错误!");
System.out.println("请输入密码:");
input=sc.nextInt();
}
}while(true);
}
}
//银联接口
interface UnionPay {
public boolean drawMoney(double number); //取钱
public boolean checkPwd(int input); //验证密码
public double getBalance(); //显示余额
}
//农行卡接口
interface ABC extends UnionPay{
public boolean payTel(String phoneNum,double calls); //支付电话费
}
//实现农行卡接口
class ABCImpl implements ABC{
private double money;
private int pwd;
public ABCImpl(double money,int pwd){
this.money=money;
this.pwd=pwd;
}
public boolean payTel(String phoneNum,double calls){
if(phoneNum.length()==11&&calls<money){
money-=calls;
return true;
}
return false;
}
public boolean drawMoney(double number){
if(number<money){
money-=number;
return true;
}
return false;
}
public boolean checkPwd(int input){
if(pwd==input){
return true;
}
return false;
}
public double getBalance(){
return money;
}
}