一分钟java小课堂_java课堂小练习8

运行以下测试代码

e8c51718ff98f1c715a034259c96f74c.png

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关键字来访问它。

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

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

怎样判断对象是否可以转换?

可以使用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

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

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) ”,因为它在编译时无法知道到底调用哪个方法。

请使用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

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

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

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

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

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

6244f2627d51f771e147181346d023a0.png

这种编程方式有什么不合理的地方吗?

算法有点复杂

结果:

我不吃肉谁敢吃肉!

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我要减肥,所以每天只吃一点大米。

我要减肥,所以每天只吃一点大米。

我要减肥,所以每天只吃一点大米。

我要减肥,所以每天只吃一点大米。

我要减肥,所以每天只吃一点大米。

fad7182b16a3831145a625823780d685.png

我不吃肉谁敢吃肉!

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我什么都吃,尤其喜欢香蕉。

我要减肥,所以每天只吃一点大米。

我要减肥,所以每天只吃一点大米。

我要减肥,所以每天只吃一点大米。

我要减肥,所以每天只吃一点大米。

我要减肥,所以每天只吃一点大米。

996e53cd8a4fe08b965165ec64632ead.png

多态编程有两种主要形式: (1)继承多态:示例程序使用的方法 (2)接口多态:使用接口代替抽象基类

用多态的方法模拟ATM操作流程:

import java.util.*;

public class ShowATM {

@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

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(" 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

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);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值