java动手动脑(多态)
1、运行以下测试代码:
public class ParentChildTest { public static void main(String[] args) { Parent parent=new Parent(); parent.printValue(); Child child=new Child(); child.printValue(); parent=child; parent.printValue();//调用子类的方法,方法中是子类的变量 parent.myValue++; parent.printValue(); ((Child)parent).myValue++; parent.printValue(); } } class Parent{ public int myValue=100; public void printValue() { System.out.println("Parent.printValue(),myValue="+myValue); } } class Child extends Parent{ public int myValue=200; public void printValue() { System.out.println("Child.printValue(),myValue="+myValue); } }
结果:
分析:前两个第一个new的parent类的对象,所以在调用时调用的是parent的构造方法以及parent的value值,第二个new的child的类的对象,所以在调用构造方法时调用child的构造方法以及child的value值。然后第三个是将子类的child赋值给了他的父类parent,在调用构造方法时也就是调用子类child的构造方法,但是在子类的构造方法时的value是子类child的value值,所以是子类child的构造方法加上value=200。第四个是parent的value值加一,但是parent仍是前面的child赋过值的,所以调用的仍然是child的构造方法,value也是child中的value所以仍是200。在最后一个中,是将parent赋给child类,所以parent也是child的一部分,所以调用时是调用子类的构造方法,并且之前value值加一了吗,所以输出201。
总结:
当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。
这个特性实际上就是面向对象“多态”特性的具体表现。
如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。
如果子类被当作父类使用,则通过子类访问的字段是父类的!
2、用多态的方法模拟ATM操作流程。
import java.util.Scanner; public class showAtm { @SuppressWarnings("resource") public static void main(String[] args) { ATM atm=new ATM(); showAtm s=new showAtm(); s.showFace(); atm.select(); } //显示菜单方法 public static void showFace(){ 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("********************"); System.out.println("请选择:"); } } class PersonalAccount{ String account; String name; String date; String mima; double yue; PersonalAccount(String account,String name,String date,String mima,double yue){ this.account=account; this.name=name; this.date=date; this.mima=mima; this.yue=yue; } String Getaccount() { return account; } String Getname() { return name; } String Getdata() { return date; } String Getmima() { return mima; } double Getyue() { return yue; } void Setaccount(String account) { this.account=account; } void Setname(String name) { this.name=name; } void Setdate(String date) { this.date=date; } void Setmima(String mima) { this.mima=mima; } void Setyue(double yue) { this.yue=yue; } } abstract class aATM{ public abstract void QuKuan();//取款 public abstract void CunKuan();//存款 public abstract void Zhuanzhang();//转账 public abstract void mima();//改密码 public abstract void yue();//余额 } class ATM extends aATM{ Scanner in = new Scanner(System.in); PersonalAccount A=new PersonalAccount("1234567890123","han","20161115","970318",1000); public void QuKuan(){ System.out.println("可取款金额:"); System.out.println("100元"); System.out.println("500元"); System.out.println("1000元"); System.out.println("1500元"); System.out.println("2000元"); System.out.println("5000元"); System.out.println("其他金额"); System.out.println("请输入你要取款的金额:"); double Q=in.nextDouble(); if(A.yue-Q<0) { System.out.println("余额不足!"); } else { System.out.println("取款成功!"); A.yue=A.yue-Q; } } public void CunKuan(){ System.out.println("请输入存款金额:"); double Q1=in.nextDouble(); A.yue=A.yue+Q1; } public void Zhuanzhang(){ System.out.println("输入要转账的行号:"); String H=in.next(); System.out.println("你要转账的人的姓名是否为xxx?0:是,1:否"); int X=in.nextInt(); if(X==0) { System.out.println("请输入要转账的金额:"); double Z=in.nextDouble(); System.out.println("转账成功!"); A.yue=A.yue-Z; System.out.println("您的余额为:"+A.yue); } if(X==1) { System.out.println("卡号错误!"); } } public void mima(){ System.out.println("请输入您要修改的卡号:"); String S=in.next(); if(A.Getaccount().equals(S)) { System.out.println("请输入原密码:"); String S1=in.next(); if(A.Getmima().equals(S1)) { System.out.println("请输入新密码:"); String S2=in.next(); A.Setmima(S2); System.out.println("修改成功!"); } } } public void yue() { System.out.println("余额为:"+A.yue); } void select(){ boolean p=true; while(p == true) { Scanner in = new Scanner(System.in); System.out.println("请输入要执行的操作:"); int m = in.nextInt(); if(m == 1) { QuKuan(); continue; } if(m == 2) { CunKuan(); continue; } if(m == 3) { Zhuanzhang(); continue; } if(m == 4) { mima(); continue; } if(m == 5) { yue(); continue; } else { System.out.println("已退出系统!"); p = false; } in.close(); } } }
结果:
3、
下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?
m=d;
d=m;
d=(Dog)m;
d=c;
c=(Cat)m;
运行以下代码:
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; } }
d=m,d=c引发错误,因为d是dog的对象,m是Mammal的对象,所以这相当于直接将父类对象给子类要用强制类型转换,c,d是同一级,同为子类,不能相互赋值。