zoukankan      html  css  js  c++  java
  • Java面向对象(六):抽象方法 & 接口 & 递归

    一、抽象类、抽象方法

    1.1 定义:

    子类继承父类时,重写了父类的方法,这个方法在父类中没有具体的实现内容,只是声明。具体的方法体由子类

    继承时重写,那么这个方法被称为抽象方法,这个父类则为抽象类。用关键字abstract修饰

    抽象方法只包含一个方法名,而没有方法体。抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

    1.2 抽象类与抽象方法之间的关联

    1、抽象类可以没有抽象方法,可以有成员方法成员变量;

    2、包含抽象方法的类一定是抽象类。

    1.3 子类继承抽象类则:

    1、若子类为非抽象类,则一定要重写父类中的抽象方法;

    2、若子类为抽象类,则可以不用实现父类的抽象方法。

    例程:studyAbstract包:AbstractDemo1.java

     1 package studyAbstract;
     2 /**
     3  * @author  Kanekiyi
     4  *抽象类与抽象方法
     5  * 
     6  * **/
     7 public abstract class AbstractDemo1 {
     8     String name;
     9     int age;
    10     
    11     /*
    12      * 抽象方法没有方法体
    13      * 有抽象方法的类一定是抽象类
    14      * 
    15      * */
    16     public abstract void study();
    17     protected abstract void study2();
    18     abstract void study3();
    19     //private abstract void study3();
    20     //public  static abstract  void study4();
    21 
    22     //抽象类中可以有成员变量和成员方法以及构造方法
    23     public void eat() {
    24         System.out.println("我吃西红柿");
    25     }
    26     
    27     public AbstractDemo1(String name, int age) {
    28         super();
    29         this.name = name;
    30         this.age = age;
    31         System.out.println("父类有参构造");
    32 
    33     }
    34 
    35     public AbstractDemo1() {
    36         super();
    37         System.out.println("父类无参构造");
    38 
    39         // TODO Auto-generated constructor stub
    40     }
    41     
    42 }
    View Code
     1 package studyAbstract;
     2 
     3 public class TextAbstractDemo1 extends AbstractDemo1 {
     4     
     5     //抽象类不能被实例化
     6     //AbstractDemo1 ad = new AbstractDemo1();
     7 
     8     //如果子类为非抽象类则必须实现抽象父类的抽象方法
     9     public void study() {
    10         System.out.println("我爱学习");
    11     }
    12 
    13     @Override
    14     protected void study2() {
    15         // TODO Auto-generated method stub
    16         
    17     }
    18 
    19     @Override
    20     void study3() {
    21         // TODO Auto-generated method stub
    22         
    23     }
    24     
    25     public static void main(String[] args) {
    26         TextAbstractDemo1 ad = new TextAbstractDemo1();
    27         ad.study2();
    28         
    29     }
    30     
    31 }
    View Code

    备注:

    1、abstract与哪些关键字不能共存?

    final:不能共存

    static:不能共存

    private: 不能共存

    2、abstract类能不能有构造函数?

    能有。构造函数作用:供子类继承时初始化成员变量

    二、递归

    方法执行过程中调用方法自身。

    例程:假设一对新生的小白兔从第三个月开始生一对小白兔,以后每个月都生一对小白兔

               新生的小白兔也从第三个月开始生小小白兔,求第n个月共有多少对小白兔。

    分析:小白兔随月份增加小白兔数量为:1 1 2 3   5 8 13 21

    代码:DiGUiDemo.java

     1 package studyAbstract;
     2 /**
     3  * 递归练习
     4  * 例程:假设一对新生的小白兔从第三个月开始生一对小白兔,以后每个月都生一对小白兔
     5               新生的小白兔也从第三个月开始生小小白兔,求第n个月共有多少对小白兔。
     6     分析:小白兔随月份增加小白兔数量为:1        1        2        3        5        8        13            21
     7     规律:从第三个数开始,每个数为之前两个数的和;
     8  * 
     9  * 
    10  * **/
    11 public class DiGuiDemo {
    12     
    13     int sum;
    14     public  int getNum(int mounth) {
    15         
    16         if(mounth==1 || mounth==2) {
    17             sum = 1;
    18         } else {
    19             //从第三个月开始每个月的兔子对数为上两个月的和
    20             sum = getNum(mounth-1) +getNum(mounth-2);
    21             
    22         }
    23         return sum;
    24     }
    25     
    26     public static void main(String[] args) {
    27         DiGuiDemo DGD = new DiGuiDemo();
    28         int mounth =8;
    29         
    30         System.out.println(mounth+"个月后共有兔子"+DGD.getNum(mounth)+"对");
    31     }
    32     
    33 }
    View Code

    三、接口

    3.1 定义:

    Java中是一个抽象类型,是抽象方法的集合。用interface修饰

    // 一个类通过继承接口的方式继承接口的抽象方法。接口可看作一个特殊的抽象类(存疑)

    3.2 接口特点:

    1、成员变量:

       接口中的成员变量都为常量;默认修饰符:public static final

    2、接口中不能有构造函数;

    3、成员方法:

      接口中的成员方法都为抽象方法;默认修饰符:public abstract

    3.3 接口与抽象类区别:

    1、声明关键字:抽象类abstract ,接口Interface

    2、成员变量:抽象类可以为变量。接口只能为常量

    3、构造函数:抽象类有,接口无;

    4、成员方法 :抽象类可以有非抽象方法的方法可以不写抽象方法,接口只能为抽象方法。

    5、抽象类实现类与类之间的共性。接口实现类的扩展性功能。

    6、接口不是被类继承了,而是要被类实现。接口支持多继承。

    3.4 接口的多继承与多实现:

    1、接口与接口之间可以多继承,extends后面用逗号隔开;

    2、类可以实现多个接口用关键字implements实现。

    备注:

    1、程序实现过程中可以将类的共性都放在抽象类中,每个类的特征性都放在接口中;

    2、非抽象类实现了接口必须重写接口的方法;抽象类可以不实现接口的方法,其子类若为非抽象类需要实现接口的方法。

    3、若父类实现了接口的抽象方法其子类可以不实现父类的抽象方法。

     练习:

    利用接口与抽象类模拟银行功能实现,要求每个银行有取钱的基础功能  ,除了取钱功能外每个银行都有自己的特色功能,比如冲话费,网上支付,透支额度等;

    功能参考如下:

    分析:

             将具有共性的功能封装在抽象类中  父类  Person类额外的抽烟功能,不具有共性。此时可以将该功能封装在一个接口中,哪个银行特有,直接

     去实现该接口即可  。

      参考代码:

          1、实现银行基础类:

     1 package textInterfaceUnionpay2;
     2 
     3 import java.util.Scanner;
     4 /***
     5  * 银联的基础类:银联下个银行共有的基础方法基础变量
     6  * @author 89869
     7  *
     8  */
     9 public abstract  class UnionpayBasis {
    10     
    11     private Scanner sc = new Scanner(System.in);
    12     private  String password;
    13     private  double balance;
    14     private boolean loginFlag;
    15     private static String bankName;
    16     
    17     //构造函数初始化登陆flag
    18     public UnionpayBasis() {
    19         super();
    20         this.loginFlag = false;
    21     }
    22     
    23     //封装成员变量
    24     public Scanner getSc() {
    25         return sc;
    26     }
    27     public void setSc(Scanner sc) {
    28         this.sc = sc;
    29     }
    30     
    31     public String getPassword() {
    32         return password;
    33     }
    34     public void setPassword(String password) {
    35         this.password = password;
    36     }
    37 
    38     public double getBalance() {
    39         return balance;
    40     }
    41     public void setBalance(double balance) {
    42         this.balance = balance;
    43     }
    44 
    45     public boolean isLoginFlag() {
    46         return loginFlag;
    47     }
    48     public void setLoginFlag(boolean loginFlag) {
    49         this.loginFlag = loginFlag;
    50     }
    51     
    52     public static String getBankName() {
    53         return bankName;
    54     }
    55     @SuppressWarnings("static-access")
    56     public void setBankName(String bankName) {
    57         this.bankName = bankName;
    58     }
    59 
    60     //银联的基础方法
    61     public abstract boolean loginSystem();
    62     public abstract void  drawMoney();
    63     
    64 }
    View Code

    2、银行的扩展接口:

     1 package textInterfaceUnionpay2;
     2 /***
     3  * 接口:银联的扩展功能
     4  * @author 89869
     5  *
     6  */
     7 public interface UnionpayExpand {
     8     
     9     //扩展功能:手机冲话费
    10     public abstract void payPhoneBills();
    11     //扩展功能:在线支付
    12     public abstract void onLinePayMent();
    13 
    14 }
    View Code

    3、银行的模板类:继承基础类,实现扩展功能接口

      1 package textInterfaceUnionpay2;
      2 
      3 import java.util.Scanner;
      4 /****
      5  * 
      6  * 银联下银行的抽象模板类:继承基础类,实现扩展接口。
      7  * 实现父类及接口的所以抽象方法,方便子类调用。
      8  * @author 89869
      9  *
     10  */
     11 public abstract class UnionpayMoudle extends UnionpayBasis implements UnionpayExpand{
     12     //获取控制台对象
     13     Scanner sc = getSc();
     14     //透支额度
     15     private  double overdraftlLmit ;
     16     
     17     //封装透支额度
     18     public double getOverdraftlLmit() {
     19         return overdraftlLmit;
     20     }
     21     public void setOverdraftlLmit(double overdraftlLmit) {
     22         this.overdraftlLmit = overdraftlLmit;
     23     }
     24 
     25     @Override//登陆系统
     26     public boolean loginSystem() {
     27         int conunt=0;
     28 
     29           while (true) { 
     30               //用户输入密码
     31               System.out.println("请在下方输入银行卡密码:");
     32               String inPassword = sc.next();
     33         
     34               //判断输入密码 是否和系统密码一样
     35               if (getPassword().equals(inPassword)) {
     36                 System.out.println("密码输入正确!");
     37                 System.out.println("用户登陆成功");
     38                 setLoginFlag(true);
     39                 break;
     40             } else {
     41                 ++conunt;
     42                 setLoginFlag(false);
     43                 int num = 3-conunt;
     44                 System.out.println("密码输入错误,你还有"+num+"次机会重新输入密码");
     45             }
     46           
     47               if (conunt>2) {
     48                 System.out.println("密码连续输入错误3次,您的卡已经被锁定请到柜台办理!");
     49                   break;
     50               }
     51           }
     52         return isLoginFlag();
     53     }
     54 
     55     @Override//取款
     56     public void drawMoney() {
     57         
     58         loop:    while  (isLoginFlag()) {
     59             System.out.println("请输入你的取款金额");
     60             double drawMoney = getSc().nextDouble();
     61             
     62             //限额,若取款金额大于余额加透支额度的和则取款失败重新输入取款金额
     63             if (drawMoney>getBalance()+getOverdraftlLmit()) {
     64                 System.out.println("您的余额不足请重新输入取款金额");
     65                 continue loop;
     66             }
     67     
     68             //计算余额
     69             setBalance(getBalance() - drawMoney);
     70             double balance = getBalance();
     71             System.out.println("取钱成功,卡余额为:"+balance);
     72 
     73             //退出系统
     74             setLoginFlag(false);
     75         } 
     76         //System.out.println("您还没有输入密码登陆,请输入密码后在登陆!");    
     77         
     78     }
     79 
     80     @Override//在线支付
     81     public void onLinePayMent() {
     82         // TODO Auto-generated method stub
     83         System.out.println("***********欢迎使用在线支付功能***********");
     84 
     85         loginSystem();
     86         
     87         while (isLoginFlag()) {
     88             System.out.println("请输入你的支付金额");
     89             double drawMoney = getSc().nextDouble();
     90             
     91             //限额
     92             if (drawMoney>getBalance()+getOverdraftlLmit()) {
     93                 System.out.println("您的余额不足请存入现金后再交易!");
     94                 //退出系统
     95                 setLoginFlag(false);    
     96                 break;
     97             }
     98             
     99             //计算余额
    100             setBalance(getBalance() - drawMoney);
    101             double balance = getBalance();
    102             System.out.println("支付成功,银行卡余额为:"+balance);
    103         
    104             //退出系统
    105             setLoginFlag(false);    
    106         }
    107 
    108     }
    109     
    110     @Override//支付电话费
    111     public void  payPhoneBills() {
    112         // TODO Auto-generated method stub
    113         System.out.println("********欢迎使用支付电话费功能********");
    114 
    115         loginSystem();
    116         
    117         while (isLoginFlag()) {
    118 
    119             System.out.println("请输入你的支付金额");
    120             double drawMoney = getSc().nextDouble();
    121             
    122             //限额
    123             if (drawMoney>getBalance() + getOverdraftlLmit()) {
    124                 System.out.println("您的余额不足请存入现金后再交易!");
    125                 //退出系统
    126                 setLoginFlag(false);    
    127                 break;
    128             }
    129             
    130             //计算余额
    131             setBalance(getBalance() - drawMoney);
    132             double balance = getBalance();
    133             System.out.println("支付成功,银行卡余额为:"+balance);
    134         
    135             //退出系统
    136             setLoginFlag(false);    
    137         }
    138 
    139     }
    140 
    141 }
    View Code

    4、实现各个银行子类

     1 package textInterfaceUnionpay2;
     2 
     3 public class ICBC extends UnionpayMoudle{
     4     public static void main(String[] args) {
     5         ICBC icbc = new ICBC();
     6         
     7         //设置登陆密码
     8         icbc.setPassword("123456");
     9         //设置银行卡余额
    10         icbc.setBalance(8000);
    11         //设置银行名称
    12         icbc.setBankName("中国工商银行");
    13         //设置透支额度
    14         icbc.setOverdraftlLmit(0);
    15           System.out.println("欢迎使用"+getBankName()+"!");
    16           
    17           //密码登陆系统
    18         icbc.loginSystem();
    19         //取钱
    20         icbc.drawMoney();
    21         //在线支付
    22         icbc.onLinePayMent();
    23         
    24     }
    25 
    26 }
    27 
    28 另一个类文件:
    29 package textInterfaceUnionpay2;
    30 
    31 import java.util.Scanner;
    32 
    33 public class ABC extends UnionpayMoudle{
    34     
    35     Scanner sc = getSc();
    36     public static void main(String[] args) {
    37         ABC abc = new ABC();
    38         abc.setPassword("123456");
    39         abc.setBalance(8000);
    40         abc.setBankName("中国农业银行");
    41         abc.setOverdraftlLmit(2000);
    42           System.out.println("**************欢迎使用"+getBankName()+"**************");
    43 
    44           abc.loginSystem();
    45           abc.drawMoney();
    46           //手机话费支付
    47           abc.payPhoneBills();
    48     }
    49 
    50 }
    View Code

       备注回头看这个代码并没有完全的体现接口的思想(将类特有共能放在接口再在类中实现),可修改为:不实现模板类,分拆银行特有功能接口类,各银行子类直接继承银行基础类并实现对应的扩展功能接口,这样做更能体现接口特性,灵活性较高,但代码复用性较低,重复代码较多。

     

      

  • 相关阅读:
    生产者消费者问题 一个生产者 两个消费者 4个缓冲区 生产10个产品
    三个线程交替数数 数到100
    c++ 字符串去重
    Java中一个方法只被一个线程调用一次
    GEF开发eclipse插件,多页编辑器实现delete功能
    python-arp 被动信息收集
    ssrf
    TCP
    xxe
    越权
  • 原文地址:https://www.cnblogs.com/Kanekiyi/p/9514763.html
Copyright © 2011-2022 走看看