zoukankan      html  css  js  c++  java
  • Java课后练习8(多态)

    动手动脑1:怎样判断对象是否可以转换?

    可以使用instanceof运算符判断一个对象是否可以转换为指定的类型: Object obj="Hello"; if(obj instanceof String) System.out.println("obj对象可以被转换为字符串");

    public class TestInstanceof
    {
    public static void main(String[] args)
    {
    //声明hello时使用Object类,则hello的编译类型是Object,Object是所有类的父类
    //但hello变量的实际类型是String
    Object hello = "Hello";
    //String是Object类的子类,所以返回true。
    System.out.println("字符串是否是Object类的实例:" + (hello instanceof Object));
    //返回true。
    System.out.println("字符串是否是String类的实例:" + (hello instanceof String));
    //返回false。
    System.out.println("字符串是否是Math类的实例:" + (hello instanceof Math));
    //String实现了Comparable接口,所以返回true。
    System.out.println("字符串是否是Comparable接口的实例:" + (hello instanceof Comparable));
    String a = "Hello";
    //String类既不是Math类,也不是Math类的父类,所以下面代码编译无法通过
    //System.out.println("字符串是否是Math类的实例:" + (a instanceof Math));
    }

    }

    结果:

    字符串是否是Object类的实例:true
    字符串是否是String类的实例:true
    字符串是否是Math类的实例:false
    字符串是否是Comparable接口的实例:true

    动手动脑2:运行以下测试代码

    1.   左边的程序运行结果是什么?
    2.   你如何解释会得到这样的输出?
    3.   计算机是不会出错的,之所以得到这样的运行结果也是有原因的,那么从这些运行结果中,你能总  结出Java的哪些语法特性?

    结果:

    Parent.printValue(),myValue=100
    Child.printValue(),myValue=200
    Child.printValue(),myValue=200
    Child.printValue(),myValue=200
    Child.printValue(),myValue=201

    总结:

    当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。

    这个特性实际上就是面向对象“多态”特性的具体表现。

    如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。

    如果子类被当作父类使用,则通过子类访问的字段是父类的!

    牢记:在实际开发中,要避免在子类中定义与父类同名 的字段。不要自找麻烦!——但考试除外,考试 中出这种题还是可以的。

    动手动脑3:下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?

    m=d; d=m; d=(Dog)m; d=c; c=(Cat)m;

    先进行自我判断,得出结论后,运行TestCast.java实例代码,看看你的判断是否正确。

    class Mammal{}
    class Dog extends Mammal {}
    class Cat extends Mammal{}

    public class TestCast
    {
    public static void main(String args[])
    {
    Mammal m;
    Dog d=new Dog();
    Cat c=new Cat();
    m=d;
    //d=m;
    d=(Dog)m;
    //d=c;
    //c=(Cat)m;

    }
    }

    编译器在编译上述代码时,采用的方法是“滞后绑定(late bind) ”,因为它在编译时无法知道到底调用哪个方法。

    动手动脑4:请使用javap查看编译器为TestPolymorphism.java生成的字节码指令,然后通过互联网搜索资料,尝试从底层开始理解Java编译器是如何为多态代码生成字节码指令,在程序运行过程中,多态特性又是如何实现的。

    class Parent

    {

    public int value=100;

    public void Introduce()
    {

    System.out.println("I'm father");

    }


    }

    class Son extends Parent
    {

    public int value=101;

    public void Introduce()
    {

    System.out.println("I'm son");

    }

    }


    class Daughter extends Parent
    {

    public int value=102;
    public void Introduce()
    {

    System.out.println("I'm daughter");

    }

    }

    public class TestPolymorphism
    {


    public static void main(String args[])
    {

    Parent p=new Parent();

    p.Introduce();

    System.out.println(p.value);

    p=new Son();

    p.Introduce();

    System.out.println(p.value);

    p=new Daughter();

    p.Introduce();

    System.out.println(p.value);


    }


    }

    结果:

    I'm father
    100
    I'm son
    100
    I'm daughter
    100

    ◆强制的:一种隐 式做类型转换的方法。

    ◆重载的:将一个标志符用作多个意义。

    ◆参数的:为不同类型的参数提供相同的操作。

    ◆包含的:类包含关系的抽象操作。

    多态依赖于类型和实现的分离,多用来把接口和实现分离。

     动手动脑5:这种编程方式有什么不合理的地方吗?

    算法有点复杂

    结果:

    我不吃肉谁敢吃肉!
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我要减肥,所以每天只吃一点大米。
    我要减肥,所以每天只吃一点大米。
    我要减肥,所以每天只吃一点大米。
    我要减肥,所以每天只吃一点大米。
    我要减肥,所以每天只吃一点大米。

    我不吃肉谁敢吃肉!
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我什么都吃,尤其喜欢香蕉。
    我要减肥,所以每天只吃一点大米。
    我要减肥,所以每天只吃一点大米。
    我要减肥,所以每天只吃一点大米。
    我要减肥,所以每天只吃一点大米。
    我要减肥,所以每天只吃一点大米。

    动手动脑6:为什么要用多态?它有什么好处?
    使用多态最大的好处是:当你要修改程序并扩充系统时,你需要修改的地方较少,对其它部分代码的影响较小!千万不要小看这两个“较”字!程序规模越大,其优势就越突出。

    动手动脑7:多态方法模仿ATM

    程序:

    import java.util.*;

    public class Test {
     @SuppressWarnings("resource")
     public static void main(String[] args) {
      Scanner in=new Scanner(System.in);
      ATM atm=new ATM();
      int choose=0,num=0;
      String pw="";
      next:while(true){
       System.out.println("是否进入账户(0否1是):");
       int kk=in.nextInt();
       if(kk==0) break;
       
       else if(kk!=1){
        System.out.println("输入错误!");
        continue;
        }
       System.out.println("输入账户密码:");
       pw=in.next();
       
       if(atm.ifPass(pw)){
        while(true){
         showFace();
         choose=in.nextInt();
         switch(choose){
         case 1:
          System.out.println("输入存款金额:");
          num=in.nextInt();
          atm.save(num);
          System.out.println("存款成功!");
          System.out.println("当前余额:"+atm.getRest()+"元");
          break;

         case 2:
          System.out.println("请选择:");
          int a[]={100,500,1000,1500,2000,5000};
          for(int i=0;i<a.length;i++)
           System.out.println((i+1)+"."+a[i]+"元");
          System.out.println("7.其他");
          int ch=in.nextInt();
          if(ch>=1&&ch<=6){
           if(atm.withdraw(a[ch-1]))
            System.out.println("取款成功!");
           
           else
            System.out.println("余额不足!");
           }
          else if(ch==7){
           System.out.println("请输入取款金额:");
           num=in.nextInt();
           
           if(atm.withdraw(num))
           System.out.println("取款成功!");
           
           else
            System.out.println("余额不足!");
           }

          else
           System.out.println("输入有误!");
          System.out.println("当前余额:"+atm.getRest()+"元");
          break;
          
         case 3:
          System.out.println("账户号:");
          String s=in.next();
          System.out.println("转账金额:");
          int i=in.nextInt();
          
          if(atm.transfer(s, i))
           System.out.println("转账成功!");

          else
           System.out.println("转账失败!");
          System.out.println("当前余额:"+atm.getRest()+"元");
          break;

         case 4:
          System.out.println("输入六位数密码:");
          String p=in.next();
          atm.setPassword(p);
          break;

         case 5:
          System.out.println("当前余额:"+atm.getRest()+"元");
          break;
          default:
           continue next;
           }
         }
        }
       
       else
        System.out.println("密码错误!");
       }
      }
     //显示菜单方法
     public static void showFace(){
      System.out.println("********************");
      System.out.println("      中国工商银行                       ");
      System.out.println(" 1.存款:");
      System.out.println(" 2.取款:");
      System.out.println(" 3.转账汇款:");
      System.out.println(" 4.修改密码:");
      System.out.println(" 5.查询余额:");
      System.out.println(" 6.退卡:");
      System.out.println("********************");
      System.out.println("请输入选项::");
      }
     }

    class PersonalAccount{
     private String passWord="123456";
     @SuppressWarnings("unused")
     private String number;//银行卡号
     private int money=0;
     public int getMoney(){return money;}
     public void setPw(String s){passWord=s;}
     public void addMoney(int x){money+=x;}
     public void minusMoney(int x){money-=x;}
     public boolean whetherPwTrue(String s){

      if(s.equals(passWord))
       return true;
      
      else
       return false;
     }
    }

    abstract class PATM{
     public abstract boolean withdraw(int x);
     public abstract void save(int x);
     public abstract boolean transfer(String s,int x);
     public abstract boolean ifPass(String s);
     public abstract int getRest();
     public abstract void setPassword(String s);//设置密码
    }

    class ATM extends PATM{
     private String numbers[]={"6227000000000000071","6227000000000000072",
       "6227000000000000073","6227000000000000074"};
     private PersonalAccount account=new PersonalAccount();
     public boolean withdraw(int x) {
      if(x>account.getMoney())
       return false;
      
      else{
       account.minusMoney(x);
       return true;
       }
      }
     
     public void save(int x) {
      account.addMoney(x);
      }
     public boolean transfer(String s, int x) {
      
      boolean flag=false;
      for(int i=0;i<numbers.length;i++)
       if(s.equals(numbers[i])) flag=true;
      if(x>account.getMoney()) flag=false;
      if(x<=account.getMoney()&&flag) account.minusMoney(x);;
      return flag;
      }
     
     public boolean ifPass(String s) {
     return account.whetherPwTrue(s);
    }
     
    public int getRest() {
     return account.getMoney();
     }
    public void setPassword(String s) {
     account.setPw(s);
     }
    }

    输出结果:

  • 相关阅读:
    字王20年
    [转]Birdfont 2.10 发布,字体编辑器
    vs2013编译boost库
    c++ 完成端口资料
    获取输入法输入内容及后选项的钩子
    unicode string和ansi string的转换函数及获取程序运行路径的代码
    c++实现输入法窗口自定义的代码
    在固定长方形里产生渐变
    监听某个div或其它标签的大小改变来执行相应的处理
    64位SqlServer通过链接服务器与32位oracle通讯
  • 原文地址:https://www.cnblogs.com/bai123/p/6077973.html
Copyright © 2011-2022 走看看