第十章 JAVA多态初步学习
来源:互联网 发布:电动汽车环保贡献数据 编辑:程序博客网 时间:2024/05/23 01:03
第一节 JAVA中的多态
对象的多种形态,继承是多态的实现基础。
1.引用多态
父类的引用可以指向本类的对象
父类的引用可以指向子类的对象
Animal obj1=new Animal();
Animal obj2=new Dog();
2.方法多态
创建本类对象,调用的方法为本类方法;创建子类对象,调用的方法为子类重写的方法或者继承的方法。如果是独有的方法(子类新建的方法,不与继承方法同名,非重写,父类的引用指向子类的对象时(多态情况下),不能调用该方法)注意不能使用子类的引用指向父类对象。
第二节 引用类型转换
这里说的对象类型转换,是指存在继承关系的对象,不是任意类型的对象。当对不存在继承关系的对象进行强制类型转换时,java 运行时将抛出 java.lang.ClassCastException 异常。
1.向上类型转换(隐式/自动类型转换),是从小类型到大类型的转换
2.向下类型转换(强制类型转换),是从大类型到小类型,这种转换有风险,可能会溢出。
3.instanceof运算符,解决引用对象的类型,避免类型转换的安全问题
在继承链中,我们将子类向父类转换称为“向上转型”,将父类向子类转换称为“向下转型”。很多时候,我们会将变量定义为父类的类型,却引用子类的对象,这个过程就是向上转型。程序运行时通过动态绑定来实现对子类方法的调用,也就是多态性。然而有些时候为了完成某些父类没有的功能,我们需要将向上转型后的子类对象再转成子类,调用子类的方法,这就是向下转型。注意:不能直接将父类的对象强制转换为子类类型,只能将向上转型后的子类对象再次转换为子类类型。也就是说,子类对象必须向上转型后,才能再向下转型。
Dog dog=new Dog();Animal animal=dog;Cat cat=(Cat)animal;
编译时不会出错(按Cat类型进行编译),但运行时会报错,因为它开辟的是Dog类型的空间,而(无法将引用类型进行转换)无法将dog对象转换成Cat类型,并且此方法对程序的安全性有影响。此时应该利用instanceof和if语句结合使用,进行验证,以保证程序的安全性,如:
if(animal instanceof Cat){//判断animal类中是否包含Cat类型的元素,若包含则进行转换,instanceof返回值为布尔类型Cat cat=(Cat)animal;}else{System.out.println("无法进行类型转换");}
instanceof可以判断一个引用是否是某个类型或者是某个类型的子类型,它会返回一个布尔值。if(animal instanceof Cat) 如果你这个对象里含有cat元素,就可以转换由于animal先被转换成了Dog类型,指向了dog的内存空间,类型不匹配。
第三节 抽象类
1.语法:抽象类前使用abstract关键字修饰
2.应用场景
- 约束子类,在某些情况下,某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法;
- 可以把有多个相同特征的类抽象出一个抽象类,以这个抽象类作为子类的模板,从而避免了子类设计的随意性
3.作用:限制规定子类必须实现某些方法,但不关注实现细节
4.使用规则:
- abstract定义抽象类
- abstract定义抽象方法,只有声明,不需要实现
- 包含抽象方法的类是抽象类
- 抽象类中可以包含普通方法,也可以没有抽象方法
- 抽象类不能直接创建,通常是使用它定义一个引用变量,指向一个子类对象
抽象类没有方法体,分号结束。public abstract void call();
第四节 JAVA中的接口
1.接口的概念:接口可以理解为一种特殊的类,由全局常量和公共的抽象方法所组成,类是一种具体的实现体,而接口定义了某一批类需要遵守的规范,接口不关心这批类的内部数据,也不关心这些类方法的实现细节,它只规定了这些类必须提供某些方法。
2.接口定义:和类定义不同,定义接口不再使用class关键字,而是使用interface关键字。
接口定义的基本语法:
修饰符 interface 接口名 extends 父接口1 父接口2…….{
0-多个常量定义….
0-多个抽象方法的定义….
}
接口就是用来被定义和实现的,修饰符一般使用public,注意不能使用private和protected修饰接口,类在JAVA中是单继承的,接口是多继承的,interface前面有abstract,不写系统也会默认添加。
常量:接口中的属性是常量,即使定义时不添加public static final修饰符,系统也会自动加上。
方法:接口中的方法只能是抽象方法,总是使用,即使定义的时候不添加 public abstract 修饰符,系统也会自动加上。
3.使用接口
一个类可以实现一个或多个接口,实现接口使用implements关键字,java中的一个类只能继承一个父类,是不够灵活的。通过实现多个接口可以作补充,一个类可以实现一个或多个接口。继承父类实现接口的语法:
修饰符 class 类名 extends 父类 implements 接口1,接口2 ….{
类体部分//如果继承了抽象类,需要实现继承的抽象方法,要实现接口中的方法
}
如果要继承父类,继承父类必须在实现接口前。接口一般是 I 字开头,使用接口的引用指向了一个实现接口的对象,之后调用方法。
接口的使用还经常与匿名内部类配合使用,匿名内部类就是没有名字的内部类,多用于关注实现而不关注实现类的名称。
语法格式:直接new一个接口,然后在接口里直接实现这个方法。
Interface i=new Interface(){public void method(){输出打印“匿名内部类实现接口的方式”}};
注意大括号后面还有个分号,接口的引用指向了一个new接口的代码,并且直接在代码里写接口的实现部分,实现以后要用分号结束,还有一种方法,直接,new 接口{方法}.方法名();直接引用,如下:
第五节 UML
1、UML概念:Unified Modeling Language(UML),又称统一建模语言或标准建模语言,是一个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持。
2、UML图示:UML2.2中一共定义了14种图示(diagrams)
3、常用UML图
用例图:用例图能够以可视化的方式,表达系统如何满足所收集的业务规则,以及特定的用户需求等信息。
序列图:序列图用于按照交互发生的一系列顺序,显示对象之间的这些交互。
类图:UML类图、业务逻辑和所有支持结构一同被用于定义全部的代码结构。
类图:类名,属性,方法,-表示私有,+表示公有
第六节 汽车租赁系统
数据分析,模型分析,业务模型分析,显示和流程分析,模拟一个汽车租赁系统。
package xuexi;/** * Created by Administrator on 2017/7/2. * 总共有三种车型:载人Auto,载货Van,载人载货Pickup * Car类为这三者的父类 * 有四种属性 * 编号=number * 品牌=brand * 租金/天=fee * 载人容量=personCapacity * 载货容量=goodCapacity */public class Car { int number; String brand; double fee; int personCapacity; double goodCapacity; public Car(int number,String brand,double fee){ this.number=number; this.brand=brand; this.fee=fee; } public int getNumber(){ return number; } public String getBrand() { return brand; } public double getFee() { return fee; } public int getPersonCapacity() { return personCapacity; } public double getGoodCapacity() { return goodCapacity; }}
package xuexi;/** * Created by Administrator on 2017/7/2. * 载人汽车,具有载人容量 */public class Auto extends Car { public Auto(int number, String brand, double fee,int personCapacity) { super(number, brand, fee); this.personCapacity=personCapacity; } @Override public String toString() { return number+"\t\t"+brand+"\t\t"+fee+"元/天\t"+"载人:"+personCapacity+"人\t"; }}
package xuexi;/** * Created by Administrator on 2017/7/2. * 载货汽车,具有载货量 */public class Van extends Car { public Van(int number, String brand, double fee,int goodCapacity) { super(number, brand, fee); this.goodCapacity=goodCapacity; } @Override public String toString() { return number+"\t\t"+brand+"\t\t"+fee+"元/天\t"+"载货:"+goodCapacity+"吨\t"; }}
/** * Created by Administrator on 2017/7/2. * 既能载人又能载货 */public class Pickup extends Car { public Pickup(int number, String brand, double fee,int personCapacity,int goodCapacity) { super(number, brand, fee); this.personCapacity=personCapacity; this.goodCapacity=goodCapacity; } @Override public String toString() { return number+"\t\t"+brand+"\t\t"+fee+"元/天'\t"+"载人:"+personCapacity+"人\t" +"载货:"+goodCapacity+"吨\t"; }}
package xuexi;import java.util.Scanner;/** * Created by Administrator on 2017/7/1. */public class Demo70101 { public static void main(String[] args) { //定义一个车辆的数组集合 Car[] cards = new Car[6]; Scanner input = new Scanner(System.in); System.out.println("欢迎使用答答租车系统:"); System.out.println("您是否要租车:1 是 2 否(请输入1或者2)"); //如果输入1或者2以外的数字需要处理下 Boolean kaiGuan = true; while (kaiGuan) { int num1 = input.nextInt(); if (num1 != 1 && num1 != 2) { System.out.println("您的选择有误请重新选择:"); } else if (num1 == 2) { kaiGuan = false; System.out.println("谢谢您的访问,再见!"); } else if (num1 == 1) { kaiGuan = false; cards[0] = new Auto(1, "奥迪A4", 500, 4); cards[1] = new Auto(2, "马自达6", 400, 4); cards[2] = new Pickup(3, "皮卡雪6", 450, 4, 20); cards[3] = new Auto(4, "金龙", 800, 20); cards[4] = new Van(5, "松花江", 400, 4); cards[5] = new Van(6, "依维柯", 1000, 20); System.out.println("您可租赁的车型及其价目表:"); System.out.println("序号\t" + "汽车名称\t" + "租金\t\t" + "容量"); for (Car c : cards) { System.out.println(c); } System.out.println("请输入您要租的车辆有几种:"); Boolean kaiGuan2 = true; while (kaiGuan2) { int num2 = input.nextInt(); if (num1 <= 00 && num1 > 6) { System.out.println("您的选择有误请重新选择:"); } else { kaiGuan2 = false; //定义一个数组来存储每辆车租用的数量。与car数组对应 int[] carNum = new int[6]; for (int i = 1; i <= num2; i++) { System.out.println("请输入您第" + i + "辆车的编号:"); int num3 = input.nextInt(); System.out.println("请输入您租" + cards[num3-1].getBrand() + "的数量:"); int num4 = input.nextInt(); carNum[num3 - 1] = num4; } System.out.println("请输入您要租的天数:"); int num5 = input.nextInt(); System.out.println("您的账单--------------------"); System.out.println("***可载人的车有:"); int personNum = 0;//定义一个数承装可载总人数 double money=0;//定义一个来装总金额 for (int i = 0; i < 6; i++) { if (carNum[i] > 0) { money+=cards[i].getFee()*carNum[i]; if (cards[i].getPersonCapacity() > 0) { System.out.println(cards[i].getBrand() + "\t" + carNum[i] + "辆"); personNum += cards[i].getPersonCapacity() * carNum[i]; } } } System.out.println("共计可载人:" + personNum + "人!"); System.out.println("***可载货的车有:"); double nums = 0;//定义一个数来承装总载货量 for (int i = 0; i < 6; i++) { if (carNum[i] > 0) { if (cards[i].getGoodCapacity() > 0) { System.out.println(cards[i].getBrand() + "\t" + carNum[i] + "辆"); nums += cards[i].getGoodCapacity() * carNum[i]; } } } System.out.println("共计可载货:" + nums + "吨!"); System.out.println("***租车总费用:"); System.out.print(money*num5+"元"); System.out.println("谢谢您的使用,欢迎您下次光临!"); } } } } }}
后面这个是第一次写的,笨的方法
测试代码package com.imooc;import java.util.Scanner;/*** Created by Administrator on 2017/3/9.*/public class Test { public static void main(String[] args) { int zuCheShuLiang = 0; int num4 = 0; int zongRenShu = 0; int zongZaiHuo = 0; int zongTianShu = 0; int zongZuJin = 0; //定义变量 System.out.println("欢迎使用答答租车系统:"); System.out.println("您是否要租车:1是 0否"); Scanner numShuRu1 = new Scanner(System.in); int num1 = numShuRu1.nextInt(); final String[][] Xinxi = {{"序号 ", "汽车名称 ", "租金 ", "容量 "}, { "1. ", "奥迪A4 ", "500元/天 ", "载人:4人 "}, { "2. ", "马自达6 ", "400元/天 ", "载人:4人 "}, { "3. ", "皮卡雪6 ", "450元/天 ", "载人:4人,载货:2吨"}, { "4. ", "金龙 ", "800元/天 ", "载人:20人 "}, { "5. ", "松花江 ", "400元/天 ", "载货:4吨 "}, { "6. ", "依维柯 ", "1000元/天 ", "载货:20吨 "}}; if (num1 == 1) { System.out.println("您可租车的类型及其价目表:"); for (int i = 0; i < Xinxi.length; i++) { for (int j = 0; j < Xinxi[i].length; j++) { System.out.print(Xinxi[i][j]); } System.out.println(); } System.out.println("近期租车人数过多,每类车型限租1辆,请输入您要租汽车的数量:"); Scanner numShuRu2 = new Scanner(System.in); int num2 = numShuRu2.nextInt(); zuCheShuLiang = num2; if (zuCheShuLiang <= 0 || zuCheShuLiang > 6) { do { System.out.println("您输入的值有误,请再次输入您要租汽车的数量:"); Scanner numShuRu3 = new Scanner(System.in); int num3 = numShuRu3.nextInt(); zuCheShuLiang = num3; num2=zuCheShuLiang; } while (zuCheShuLiang <= 0||zuCheShuLiang > 6); } String[] cheName = new String[zuCheShuLiang]; AoDi car1 = new AoDi(); MaZiDa car2 = new MaZiDa(); PiKaXue car3 = new PiKaXue(); JinLong car4 = new JinLong(); SongHuaJiang car5 = new SongHuaJiang(); YiWeiKe car6 = new YiWeiKe(); for (int x = 0; zuCheShuLiang > 0; zuCheShuLiang--, x++) { System.out.println("请输入第" + (x + 1) + "辆车的序号:"); Scanner numShuRu4 = new Scanner(System.in); num4 = numShuRu4.nextInt(); switch (num4) { case 1: cheName[x] = car1.carName; zongRenShu = zongRenShu + car1.zaiRen; zongZaiHuo = zongZaiHuo + car1.zaiHuo; zongZuJin = zongZuJin + car1.zuJin; continue; case 2: cheName[x] = car2.carName; zongRenShu = zongRenShu + car2.zaiRen; zongZaiHuo = zongZaiHuo + car2.zaiHuo; zongZuJin = zongZuJin + car2.zuJin; continue; case 3: cheName[x] = car3.carName; zongRenShu = zongRenShu + car3.zaiRen; zongZaiHuo = zongZaiHuo + car3.zaiHuo; zongZuJin = zongZuJin + car3.zuJin; continue; case 4: cheName[x] = car4.carName; zongRenShu = zongRenShu + car4.zaiRen; zongZaiHuo = zongZaiHuo + car4.zaiHuo; zongZuJin = zongZuJin + car4.zuJin; continue; case 5: cheName[x] = car5.carName; zongRenShu = zongRenShu + car5.zaiRen; zongZaiHuo = zongZaiHuo + car5.zaiHuo; zongZuJin = zongZuJin + car5.zuJin; continue; case 6: cheName[x] = car6.carName; zongRenShu = zongRenShu + car6.zaiRen; zongZaiHuo = zongZaiHuo + car6.zaiHuo; zongZuJin = zongZuJin + car6.zuJin; continue; } } System.out.println("请输入您租车的天数:"); Scanner numShuRu5 = new Scanner(System.in); zongTianShu = numShuRu5.nextInt(); System.out.println("您的账单:"); System.out.println("***可载人的车有:"); for (int y = 0; y < num2; y++) { if ((cheName[y]==car1.carName) && (car1.zaiRen > 0))System.out.print(cheName[y]+" "); if ((cheName[y]==car2.carName) && (car2.zaiRen > 0)) System.out.print(cheName[y]+" "); if ((cheName[y]==car3.carName) && (car3.zaiRen > 0)) System.out.print(cheName[y]+" "); if ((cheName[y]==car4.carName) && (car4.zaiRen > 0)) System.out.print(cheName[y]+" "); if ((cheName[y]==car5.carName) && (car5.zaiRen > 0)) System.out.print(cheName[y]+" "); if ((cheName[y]==car6.carName) && (car6.zaiRen > 0)) System.out.print(cheName[y]+" "); } System.out.println(" 共载人:" + zongRenShu + "人"); System.out.println("***可载货的车有:"); for (int y = 0; y < num2; y++) { if ((cheName[y]==car1.carName) && (car1.zaiHuo > 0)) System.out.print(cheName[y]+" "); if ((cheName[y]==car2.carName) && (car2.zaiHuo > 0)) System.out.print(cheName[y]+" "); if ((cheName[y]==car3.carName) && (car3.zaiHuo > 0)) System.out.print(cheName[y]+" "); if ((cheName[y]==car4.carName) && (car4.zaiHuo > 0)) System.out.print(cheName[y]+" "); if ((cheName[y]==car5.carName) && (car5.zaiHuo > 0)) System.out.print(cheName[y]+" "); if ((cheName[y]==car6.carName) && (car6.zaiHuo > 0)) System.out.print(cheName[y]+" "); } System.out.println(" 共载货:" + zongZaiHuo + "吨"); System.out.println("租车总价格:" + zongTianShu * zongZuJin + "元"); } }}父类public class Car { String carName; int zuJin; int zaiRen; int zaiHuo; int bianHao;}子类public class AoDi extends Car { String carName="奥迪A4"; int zuJin=500; int zaiRen=4; int zaiHuo=0; int bianHao=1; }public class JinLong extends Car { String carName="金龙"; int zuJin=800; int zaiRen=20; int zaiHuo=0; int bianHao=4; }public class MaZiDa extends Car { String carName="马自达6"; int zuJin=400; int zaiRen=4; int zaiHuo=0; int bianHao=2;}public class SongHuaJiang extends Car { String carName="松花江"; int zuJin=400; int zaiRen=0; int zaiHuo=4; int bianHao=5;}public class YiWeiKe extends Car { String carName="依维柯"; int zuJin=1000; int zaiRen=0; int zaiHuo=20; int bianHao=6;}
- 第十章 JAVA多态初步学习
- java多态初步
- java线程初步学习
- java JNI 初步学习
- java初步jni学习
- JAVA初步学习--环境变量
- JAVA BigDecimal初步学习
- java数组初步学习
- java注解初步学习
- Java反射初步学习
- JAVA学习初步
- java学习初步记录
- java学习初步总结
- Java swing初步学习
- java多线程初步学习
- Java基础学习《第十章 内部类》
- 《java语言程序设计》第十章学习总结
- Java学习第十天
- Processing binary structured data with Python
- Socket编程(二)随时接收客户端消息及多客户端连接
- 第九章 JAVA中的继承
- 对象存储Amazon S3的诞生
- 动态规划专题之----198. House Robber
- 第十章 JAVA多态初步学习
- 一些常用数据结构的数组实现 不定期更新
- maven 学习笔记(一)安装
- OpenStack Swift发展历程
- 第十一章 JAVA异常与异常处理
- Linux Netcat 命令——网络工具中的瑞士军刀
- RCNN学习笔记(00)简介
- 第十二章 JAVA中的字符串及常用方法
- hibernate:many to one