动手实验一:下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?
m=d;
d=m;
d=(Dog)m;
d=c;
c=(Cat)m;
先进行自我判断,得出结论后,运行TestCast.java实例代码,看看你的判断是否正确:
java中基类对象不能当做子类对象使用,需要用强制转换来实现,子类对象变量=(子类名)基类对象名;错误的代码是d=m; d=c;
错误原因:类型不匹配:不能从 Mammal 转换为 Dog。
动手实验二:运行以下测试代码
上边的程序运行结果是什么?.你如何解释会得到这样的输出?计算机是不会出错的,之所以得到这样的运行结果也是有原因的,那么从这些运行结果中,你能总结出Java的哪些语法特性?请务必动脑总结,然后修改或编写一些代码进行测试,验证自己的想法,最后再看后面的PPT给出的结论。
如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。
如果子类被当作父类使用,则通过子类访问的字段是父类的!
第一个value调用的是父类的方法,输出值为100
第二个value调用的是子类的方法,输出值为200
第三个中子类赋值给父类,因此调用了子类的方法,输出值为200
第四个中调用了子类的构造方法,但是value值为100,所以没有影响
第五个中调用的是子类的方法,value的值也是子类的
改写一:
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++;
System.out.println(parent.myValue);
System.out.println(child.myValue);
parent.printValue();
/*((Child)parent).myValue++;
System.out.println(parent.myValue);
System.out.println(child.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);
}
}
改写二:
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++;
System.out.println(parent.myValue);
System.out.println(child.myValue);
parent.printValue();*/
((Child)parent).myValue++;
System.out.println(parent.myValue);
System.out.println(child.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);
}
}
运行截图2:
编译器在编译上述代码时,采用的方法是“滞后绑定(late bind) ”,因为它在编译时无法知道到底调用哪个方法。
请使用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
◆强制的:一种隐 式做类型转换的方法。
◆重载的:将一个标志符用作多个意义。
◆参数的:为不同类型的参数提供相同的操作。
◆包含的:类包含关系的抽象操作。
多态依赖于类型和实现的分离,多用来把接口和实现分离。
ATM:import java.util.*;
//ATM的界面类
abstract class QuKuan
{
abstract int qukuan();
}
class ATMview extends QuKuan{
public Scanner sc = new Scanner(System.in);
public User user =new User(20153197,123456,20000.00);
//欢迎界面
public void welcome(){
System.out.println("请选择语言界面 1汉语 2英语");
int yuyan=sc.nextInt();
System.out.println("欢迎使用ATM自动取款机");
login();
}
//登陆
public void login(){
for(int i=3;i>0;i--){
System.out.println("请输入账号:");
int account = sc.nextInt();
System.out.println("请输入密码:");
int pwd = sc.nextInt();
if(account==20153197 && pwd==123456){
System.out.println("登陆成功!请继续你的操作");
menu();
} else{
System.out.println("账号密码有误该卡已被锁定!");
}
}
System.exit(0);
}
public class User {
//账号
public int account;
//密码
public int pwd;
//余额
public double money;
//建立User的有参构造器
public User(int account,int pwd,double money){
this.account = account;
this.pwd = pwd;
this.money = money;
}
//存款
public void save(double money){
this.money+=money;
}
//取款
public void get(double money){
this.money-=money;
}
//查询
public double search(){
this.money=money;
return money;
}
public void zhuanzhang(double money)
{
this.money=money;
}
}
//菜单
public void menu(){
System.out.print("1存款2取款3查询余额4转账汇款5修改密码6退出");
int input = sc.nextInt();
switch(input){
//存款
case 1: saveView();
break;
//取款
case 2: getView();
break;
//查询余额
case 3: searchView();
break;
//转账汇款
case 4: zhuanzhangView();
break;
//修改密码
case 5: xiugaiView();
break;
case 6:System.out.println("系统已退出!欢迎下次光临");
break;
}
}
//存款的界面
public void saveView(){
System.out.println("请输入存款金额: ");
double money = sc.nextInt();
user.save(money+sc.nextInt());
menu();
}
//取款的界面
public void getView(){
System.out.println("请输入取款金额:1.100元 2.500元 3.1000元 4.1500元 5.2000元 6.5000元 7.其他金额 8.选择其他金额 9.退卡");
int qukuan=sc.nextInt();
if(sc.nextInt()==1);
double money=0;
if(money>user.money){
System.out.println("你的余额不足");
menu();
}else{
user.get(money+100);
System.out.println("已经取出100元");
System.out.println("请选择其他服务!!!");
}
menu();
}
//查询余额的界面
public void searchView(){
double money = user.search();
System.out.println("你的余额为:"+money);
menu();
}
//转账汇款的界面
public void zhuanzhangView()
{
System.out.println("请输入要存的账号");
int account=sc.nextInt();
System.out.println("请输入要转账的钱数");
int money=sc.nextInt();
}
//修改密码的界面
public void xiugaiView()
{
System.out.println("输入新的密码");
int pwd=sc.nextInt();
System.out.println("新的密码为:"+sc.nextInt());
System.out.println("请选择其他服务!!!");
menu();
}
int qukuan() {
// TODO Auto-generated method stub
return 0;
}
}
//Main方法调用
public class Testmain {
public static void main(String[]args){
ATMview view = new ATMview();
view.welcome();
}
}