2016.11.18多态

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

m=d;

d=m;

d=(Dog)m;

d=c;

c=(Cat)m;

结论:

java中基类对象不能当做子类对象使用,需要用强制转换来实现,子类对象变量=(子类名)基类对象名;错误的代码是d=m; d=c;

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

运行结果截图:

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

}

}

结论:

当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。
这个特性实际上就是面向对象“多态”特性的具体表现。

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

第一个value调用的是父类的方法,输出值为100

第二个value调用的是子类的方法,输出值为200

第三个中子类赋值给父类,因此调用了子类的方法,输出值为200

第四个中调用了子类的构造方法,但是value值为100,所以没有影响

第五个中调用的是子类的方法,value的值也是子类的

请使用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操作流程。

package dome;
//2016.11.18    20153314    严鹏    多态法
import java.util.*;
public class S2{

public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner in=new Scanner(System.in);
ATM atm=new ATM();
int choose=0,num=0,p2=1;
String pw;
System.out.println("输入账户密码:");
pw=in.next();
if(atm.ifPass(pw)){
while(p2==1){

    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("请选择:");
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;

}
}
}
else
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{                //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{          //ATM继承抽象类来并实现抽象方法
private String numbers[]={"3235635","3256894",
"3265894","6589458"};
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);
}
}
时间: 2024-12-26 09:39:41

2016.11.18多态的相关文章

【2016.11.18】进制转换

二进制:0.1       逢二进一    基数:2 需要用二进制来表示一个2 0.1 八进制:0~7        逢八进一    基数:8     2^3=8  一个八进制可以表示3位二进制 使用八进制表示8  10 0.1.2.3.4.5.6.7  表示8 (10)8 十进制:0~9        逢十进一    基数:10 0.1.2.3.4.5.6.7.8.9     表示10 10 十六进制:0~F      逢十六进一    基数:16    2^4 = 16  一个十六进制可以表

2016.11.18

  整理: <from></from>创建一个表单 文本输入: <input type="text" value=""(值)  id=""(相当于身份证,唯一的) disabled="disabled"(锁定) required="required"(必填)/> 文本框 是单独出现的 <input type="password" value=&q

python网络编程学习2016/11/18

1.打印本机设备名以及IPv4地址 #!/usr/bin/python2.7 # -*- coding=utf-8 -*- import socket def print_machine_info(): host_name = socket.gethostname()                       #本机设备名 ip_address = socket.gethostbyname(host_name)   #设备名对应的ip 地址 print "%s \'s ip is %s&quo

每周进度及工作量统计——2016.11.24-2016.11.30

项目:连连看游戏 项目类型:四人小组项目 小组名称:天天向上 小组成员:王森.张政,张金生,栾骄阳 项目改进:final版本研发和维护 项目预期时间:2016.9.10-2016.12.8 2016.11.26-2016.11.27 C类别 C内容 S开始时间 E结束时间 I间隔 T净时间 P预计时间 分析 讨论  13:24  13:43  0  19  20   设计  13:43  14:04  0  21  30 编码 功能优化  14:46  16:51  26  99  120 文档

Welcome to Swift (苹果官方Swift文档初译与注解三)---11~18页

上述代码中,如果可选值为nil,那么判断条件则为false,而且在{}中的代码将会被忽略,如果可选值不为nil,会将该值逐步运算后赋值给let后面的常量,其中逐步运算过程将依据实际的代码块. Switch 语法支持任何类型数据以及各种比较操作,并不局限在整型. let vegetable = "red pepper" switch vegetable { case "celery": let vegetableComment = "Add some rai

Chap3: question: 11 - 18

11. double 数值的整数次方 note: 浮点数表示时有误差,判等时必须自己根据精度要求实现. + ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <iostream> #incl

11.18 Apache用户认证11.19 11.20 域名跳转11.21 Apache访问日志

11.18 Apache用户认证更改虚拟主机内容vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf增加用户名与密码? /usr/local/apache2.4/bin/htpasswd -c -m /data/.htpasswd aming-c是创建 -m指定类型查看生成的密码文档内容上面已经他去了.htpasswd目录,再创建用记就不需要-c在wi上指定域名hostsC:\Windows\System32\drivers\etc认证:没有

2016/04/18 ①注册 注册处理 ② 审核 审核处理 ③登录 登录处理 ④需要jquery-1.11.2.min.js DBDA.php

① 注册   zhuceye.php 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <script src="jquery-1.11.2.min.js"></script> 7 </head>

挨踢周刊2016/11/16

2016年11月16日至18日,第三届世界互联网大会在浙江乌镇举办,中共中央总书记.国家主席习近平在开幕式上发表视频讲话.马化腾.马云.李彦宏.雷军.丁磊.周鸿祎.曹国伟.王小川.沈南鹏.杨元庆.张亚勤和刘强东等国内互联网巨头领军人物悉数到场参加. 2016年"双11"是阿里巴巴在美国上市后的第三个网购狂欢.北京时间周五凌晨,在亿万剁手党的共同努力下,"双11"开场后,成交额仅用6分58秒就突破100亿元大关,2015年为12分28秒:此后成交额一路攀升,最终在24