面向对象回顾
面向对象的软件开发方法
-
*软件系统即各种对象的集合
-
按对象设计出来的系统结构较稳定
-
子系统相对独立,提高了软件的可维护性
-
支持封装、继承和多态,提高了软件的可重用性和可扩展性
万物皆对象 -
软件系统所模拟的真实世界中,所有的实体都可以抽象为对象
-
每个对象都是唯一的
对象
- 对象具有属性和行为(方法)
- 对象具有状态
1、 状态指某个瞬间对象各种属性的取值
2、对象的方法可以改变对象自身的状态 - 对象都属于某个类,每个对象都是某个类的实例
类
- 类是一组具有相同属性和行为的对象的抽象
- 开发人员自定义数据类型
- 面向对象编程的主要任务就是定义各类
- 对象是类的实例,类是对象的模板
面向对象三大特征
面向对象三大特征
-
封装
-
继承
-
多态
封装 -
隐藏对象的属性和实现细节,仅仅对外公开接口
-
便于使用者正确方便的理解和使用系统
-
有助于各系统之间的松耦合,提高系统独立性
-
提高软件的可重用性
-
把尽可能多的东西藏起来,对外提供便捷的接口
-
把所有的属性藏起来(private)
继承
子类、父类
- 子类继承了父类的部分属性和方法(extends)
- 子类还可以扩展出新的属性和方法
- 子类还可以覆盖父类中方法的实现方式(方法重写,可以用super调用)
注意 - 继承的层次不可太多,尽量两到三层
- 继承的最上层最好是抽象的
多态
多态
-
多种实现方式提供服务
动态绑定 -
实例方法(动态绑定机制) 与引用变量实际引用的对象绑定,调用重写后的方法,由运行时的jvm决定
静态绑定
- 静态方法(静态绑定机制) 与引用变量所声明的类型绑定。实际上在编译阶段就做了绑定
成员变量 - 成员变量(包括静态变量和实例变量,静态绑定机制) 与引用变量所声明的类型绑定。实际上在编译阶段就做了绑定
向上转型
-
把引用变量转换为父类类型
向下转型 -
把引用变量转换为子类类型
Per pet = new Dog();
Dog dog = (Dog)pet; //向下转型
Animal animal = pet; //向上转型
面向对象应用
某汽车租赁公司出租多种轿车和客车,出租费用以日为单位计算。出租车型及信息如下表所示
车型 | 具体信息 | 日租金 | 折扣 |
---|---|---|---|
轿车 | 宝马X6(京NY22258) | 800 | days>7天9折 days>30天8折 days>150天7折 |
轿车 | 宝马550i(京CN646664) | 600 | 同上 |
轿车 | 别克林荫大道(京NT666688) | 300 | 同上 |
轿车 | 别克GL8(京NT969698) | 600 | 同上 |
客车 | 金杯,16座(京6566754) | 800 | days>=3天9折 days>=7天8折 days>=30天7折 days>=150天6折 |
客车 | 金龙,16座(京8688688) | 800 | 同上 |
客车 | 金杯,34座(京96979896) | 1500 | 同上 |
客车 | 金龙,34座(京86889688) | 1500 | 同上 |
面向对象设计步骤
抽象出类
找出问题中的名词:
类的属性
类和类的属性:
- 汽车类:车牌号、品牌、日租金
- 客车类:车牌号、品牌、日租金、座位数
- 轿车类:车牌号、品牌、日租金、型号
- 汽车业务类:忽略
- 汽车租赁管理类:忽略
类的方法
找出问题中的动词
** 优化设计**
设计类:
- 汽车设计为抽象类
设计方法:
- 计算租金设计为抽象方法
OK!分析完步骤后,接下来,上代码—>
package cn.pb.cars;
//汽车类
public abstract class MotoVehicle {
//车牌号 品牌 日租金
private String vehicleID;
private String brand;
private int perRent;
public MotoVehicle(){
}
public MotoVehicle(String vehicleID, String brand, int perRent) {
this.vehicleID = vehicleID;
this.brand = brand;
this.perRent = perRent;
}
public String getVehicleID() {
return vehicleID;
}
public void setVehicleID(String vehicleID) {
this.vehicleID = vehicleID;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getPerRent() {
return perRent;
}
public void setPerRent(int perRent) {
this.perRent = perRent;
}
//计算租金(抽象方法)
public abstract float clacRent(int days);
}
//汽车(品牌 日租金 车牌号)-->抽象类 (计算租金 抽象方法)
//轿车(品牌 日租金 车牌号 型号)
//客车(品牌 日租金 车牌号 座位数)
//
//汽车业务类:
//初始化车:数组(汽车)
//
//租车(租给用户一辆车,返回值是汽车):
//类型(轿车 客车)
//
//轿车(品牌 型号 天数)
//客车(品牌 座位数 天数)
//根据用户提出的租赁条件去汽车数组中查找
package cn.pb.cars;
//客车类
public class Bus extends MotoVehicle {
//座位数
private int seatCount;
public int getSeatCount() {
return seatCount;
}
public void setSeatCount(int seatCount) {
this.seatCount = seatCount;
}
public Bus(){
}
public Bus(String vehicleID, String brand, int perRent,int seatCount) {
super(vehicleID, brand,perRent);
this.seatCount = seatCount;
}
//重写父类的计算租金方法:根据自己的计算租金规则
public float clacRent(int days){
float price = this.getPerRent()*days;
if(days>=3 && days<7){
price*=0.9f;
}else if(days>=7 && days<30){
price*=0.8f;
}else if(days>=30 && days<150){
price*=0.7f;
}else if(days>=150){
price*=0.6f;
}
return price;
}
}
package cn.pb.cars;
//轿车类
public class Car extends MotoVehicle {
//型号
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Car(){
}
public Car(String vehicleID, String brand, int perRent,String type) {
super(vehicleID, brand,perRent);
this.type = type;
}
//重写父类的计算租金方法:根据自己的计算租金规则
public float clacRent(int days){
float price = this.getPerRent()*days;
if(days>7 && days<=30){
price*=0.9f;
}else if(days>30 && days<=150){
price*=0.8f;
}else if(days>150){
price*=0.7f;
}
return price;
}
}
package cn.pb.manage;
import cn.pb.cars.Bus;
import cn.pb.cars.Car;
import cn.pb.cars.MotoVehicle;
//汽车业务类
public class MotoOperation {
//汽车类型的数组,将该数组声明为父类类型
public MotoVehicle[] motos = new MotoVehicle[8];
//初始化汽车信息
public void init(){
motos[0] = new Car("京NY78654","宝马",800,"X6"); //MotoVehicle m =new Car();
motos[1] = new Car("京NY56457","宝马",600,"550i"); //MotoVehicle m =new Car();
motos[2] = new Car("京NY78454","别克",300,"林荫大道"); //MotoVehicle m =new Car();
motos[3] = new Car("京NT75554","别克",800,"GL8"); //MotoVehicle m =new Car();
motos[4] = new Bus("京NI88899","金杯",800,16); //MotoVehicle m =new Bus();
motos[5] = new Bus("京NL45678","金龙",800,16); //MotoVehicle m =new Bus();
motos[6] = new Bus("京NY78644","金杯",1500,34); //MotoVehicle m =new Bus();
motos[7] = new Bus("京NY78454","金龙",1500,34); //MotoVehicle m =new Bus();
}
//租车:根据用户提供的条件去汽车数组中查找相应车辆并返回
//如果租赁的是客车 需要的条件:品牌 座位数 型号null
//如果租赁的是轿车 需要的条件: 品牌 型号 座位数为0
public MotoVehicle motoLeaseOut(String brand,String type,int seat){
MotoVehicle moto = null;
for(MotoVehicle mymoto : motos){
if(mymoto instanceof Car){
Car car = (Car)mymoto;
if(car.getBrand().contentEquals(brand) && car.getType().equals(type)){
moto = car;
break;
}
}else{
Bus bus = (Bus)mymoto;
if(bus.getBrand().contentEquals(brand) && bus.getSeatCount()==seat){
moto = bus;
break;
}
}
}
return moto;
}
}
package cn.pb.manage;
import java.util.Scanner;
import cn.pb.cars.MotoVehicle;
//汽车租赁管理类:测试类
public class RentMgrSys {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
MotoOperation motoMgr = new MotoOperation();
//租赁公司首先需要购置汽车
motoMgr.init();
System.out.println("***************欢迎光临租赁公司****************");
System.out.println("1 轿车\t2 客车");
System.out.println("请选择您要租赁的汽车类型");
int motoType = input.nextInt();
String brand = "";//品牌
String type = "";//型号
int seat = 0;//座位数
//收集用户条件
if(motoType == 1){
//租赁轿车
System.out.println("请选择您要租赁的轿车品牌:1.别克 2.宝马");
int choose = input.nextInt();
if(choose == 1){
brand = "别克";
System.out.println("请选择您要租赁的汽车型号:1.林荫大道 2.GL8");
type = (input.nextInt() == 1)?"林荫大道":"Gl8";
}else if (choose == 2){
brand = "宝马";
System.out.println("请选择您要租赁的汽车型号:1.X6 2.550i");
type = (input.nextInt() == 1)?"X6":"550i";
}
}else if(motoType == 2){
//租赁客车
type = "";
System.out.println("请选择您要租赁的客车品牌:1.金杯 2.金龙");
brand = (input.nextInt()==1)?"金杯":"金龙";
System.out.println("请选择您要租赁的客车座位数:1.16座 2.34座");
seat = (input.nextInt()==1)?16:34;
}
//租车
MotoVehicle moto = motoMgr.motoLeaseOut(brand, type, seat);
System.out.println("请输入您的租赁天数:");
int days = input.nextInt();
float money = moto.clacRent(days);
System.out.println("租车成功,请按照如下车牌号去提车:"+moto.getVehicleID());
System.out.println("您需要支付:"+money+"元");
}
}