多态
1. 定义
-
同一个引用类型,使用不同的实例而执行的操作,实现多种形态。
-
创建一个对象以父类类型接收,因创建的实例不同,而表现出不同的形态,多态一定要在继承关系下的方法重写的情况下才能实现。
2.多态有两种体现方式
2.1、使用父类作为方法的形参实现多态
示例:通过食堂给不同的人打饭,方式和价格都不同
-
父类person类
/** * 父类-人类 * @author Administrator * */ public abstract class Person { String name; int age; String sex; double money; public Person() { super(); } public Person(String name, int age, String sex) { super(); this.name = name; this.age = age; this.sex = sex; } /** * 吃饭方法 */ public abstract void eat(); }
-
子类1-student类
/** * 子类-学生类 * @author Administrator * */ public class Student extends Person{ public Student() { super(); // TODO Auto-generated constructor stub } public Student(String name, int age, String sex) { super(name, age, sex); // TODO Auto-generated constructor stub } public void eat() { System.out.println("学生去食堂吃饭"); if(super.age>20) { money=20; }else { money=15; } } public void showStudent() { System.out.println("这是学生的特有方法"); } }
-
子类2-teacher类
/** * 子类-老师类 * @author Administrator * */ public class Teacher extends Person{ public Teacher() { super(); // TODO Auto-generated constructor stub } public Teacher(String name, int age, String sex) { super(name, age, sex); // TODO Auto-generated constructor stub } @Override public void eat() { System.out.println("老师吃小灶"); if("男".equals(super.sex)) { money=25; }else { money=20; } } public void showTeacher() { System.out.println("这是老师的特有方法"); } }
-
子类3-headerMaster类
/** * 子类-校长类 * @author Administrator * */ public class HeaderMaster extends Person{ public HeaderMaster() { super(); // TODO Auto-generated constructor stub } public HeaderMaster(String name, int age, String sex) { super(name, age, sex); // TODO Auto-generated constructor stub } @Override public void eat() { System.out.println("校长,吃豪华套餐"); money=0; } public void showHeaderMaster() { System.out.println("这是校长的特有方法"); } }
-
实现需求的类-食堂类
import java.util.Scanner; /** * 食堂类 * @author Administrator * */ public class FoodRoom { //打饭 public void dafan(Person person) { //以父类类型接收,因子类实例不同而会调用到不同子类被重写的方法,从而表现多态! person.eat(); System.out.println("姓名:"+person.name+"\t年龄:"+ person.age+"\t性别:"+person.sex+"\t价格:" + person.money); //调用不同子类的特有方法--->向下转型 if(person instanceof Student) { Student student=(Student)person; student.showStudent(); }else if(person instanceof Teacher) { Teacher teacher=(Teacher)person; teacher.showTeacher(); }else if(person instanceof HeaderMaster) { HeaderMaster head=(HeaderMaster)person; head.showHeaderMaster(); } } }
-
测试类
public class Test { public static void main(String[] args) { FoodRoom fr = new FoodRoom(); Person person=null; person=new Student("张三",20,"男"); fr.dafan(person); person=new Teacher("李四",30,"男"); fr.dafan(person); person=new HeaderMaster("王五",40,"男"); fr.dafan(person); } }
-
结果
学生去食堂吃饭 姓名:张三 年龄:20 性别:男 价格:15.0 这是学生的特有方法 老师吃小灶 姓名:李四 年龄:30 性别:男 价格:25.0 这是老师的特有方法 校长,秘书喂饭! 姓名:王五 年龄:40 性别:男 价格:0.0 这是校长的特有方法
2.2、使用父类作为方法的返回值实现多态
示例:通过选择不同的职业,食堂的价格不同
-
食堂类
import java.util.Scanner; /** * 食堂类 * @author Administrator * */ public class FoodRoom { //打饭 public void dafan(Person person) { //以父类类型接收,因子类实例不同而会调用到不同子类被重写的方法,从而表现多态! person.eat(); System.out.println("姓名:"+person.name+"\t年龄:"+ person.age+"\t性别:"+person.sex+"\t价格:" + person.money); //调用不同子类的特有方法--->向下转型 if(person instanceof Student) { Student student=(Student)person; student.showStudent(); }else if(person instanceof Teacher) { Teacher teacher=(Teacher)person; teacher.showTeacher(); }else if(person instanceof HeaderMaster) { HeaderMaster head=(HeaderMaster)person; head.showHeaderMaster(); } } public Person choice(String name, int age, String sex) { Person person=null; Scanner input = new Scanner(System.in); System.out.println("请选择职业:1.学生2.老师3.校长"); int choise =input.nextInt(); switch (choise) { case 1: person=new Student(name,age,sex); break; case 2: person=new Teacher(name,age,sex); break; case 3: person=new HeaderMaster(name,age,sex); break; default: break; } return person; } }
-
测试类
public class Test { public static void main(String[] args) { FoodRoom fr = new FoodRoom(); fr.dafan(fr.choice("李四",30,"男")); } }
-
结果
请选择职业:1.学生2.老师3.校长 1 学生去食堂吃饭 姓名:李四 年龄:30 性别:男 价格:20.0 这是学生的特有方法
2.3、示例3
以上面的的基础加上吃饭天数,计算所有人要交的总价:
-
所有的父类,子类都加上天数
private int day;
-
食堂类
import java.util.Scanner; /** * 食堂类 * @author Administrator * */ public class FoodRoom { //打饭 public void dafan(Person person) { //以父类类型接收,因子类实例不同而会调用到不同子类被重写的方法,从而表现多态! person.eat(); System.out.println("姓名:"+person.name+"\t年龄:"+ person.age+"\t性别:"+person.sex+"\t价格:" + person.money); //调用不同子类的特有方法--->向下转型 if(person instanceof Student) { Student student=(Student)person; student.showStudent(); }else if(person instanceof Teacher) { Teacher teacher=(Teacher)person; teacher.showTeacher(); }else if(person instanceof HeaderMaster) { HeaderMaster head=(HeaderMaster)person; head.showHeaderMaster(); } } public Person choice(String name, int age, String sex,int day) { Person person=null; Scanner input = new Scanner(System.in); System.out.println("请选择职业:1.学生2.老师3.校长"); int choise =input.nextInt(); switch (choise) { case 1: person=new Student(name,age,sex,day); break; case 2: person=new Teacher(name,age,sex,day); break; case 3: person=new HeaderMaster(name,age,sex,day); break; default: break; } return person; } public double getTotalMoneys(day02.Person[] persons) { double total=0; double totalmoney=0; for (int i = 0; i < persons.length; i++) { if(persons[i]!=null) { persons[i].eat(); total=persons[i].money*persons[i].day; System.out.println("总价:"+total); totalmoney+=total; } } return totalmoney; } }
-
测试类
public class Test { public static void main(String[] args) { FoodRoom fr = new FoodRoom(); Person persons[]=new Person[5]; persons[0]=new Student("李一",20,"男",8); persons[1]=new Teacher("李二",40,"男",5); persons[2]=new Teacher("李三",45,"男",5); persons[3]=new HeaderMaster("李四",65,"男",8); double totalmoneys = fr.getTotalMoneys(persons); System.out.println("所有人的总价" + totalmoneys); } }
-
结果
学生去食堂吃饭 总价:120.0 老师吃小灶 总价:125.0 老师吃小灶 总价:125.0 校长,秘书喂饭! 总价:0.0 所有人的总价370.0
3.案例:汽车租赁系统
目的:通过顾客选择不同的汽车租赁不同的天数计算应该交多少钱
-
父类-Motovehicle类
/** * 机动车类 * @author Administrator * */ public abstract class MotoVehicle { private String no;//汽车编号 private String brand;//汽车品牌 public MotoVehicle() { super(); } public MotoVehicle(String no, String brand) { super(); this.no = no; this.brand = brand; } public String getNo() { return no; } public void setNo(String no) { this.no = no; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } /** * 计算汽车租赁的方法 */ public abstract int calRent(int days); }
-
子类1-Bus类
/** * 客车 * @author Administrator * */ public class Bus extends MotoVehicle{ private int setCount;//座位数 public Bus() { } public Bus(String no, String brand,int setCount) { super(no, brand); this.setCount=setCount; } public int getSetCount() { return setCount; } public void setSetCount(int setCount) { this.setCount = setCount; } @Override public int calRent(int days) { //如果座位数小于18人的是800一天,day18人的是1500一天 if(this.setCount<18) { return days*800; }else { return days*1500; } } }
-
子类2-car类
/** * 小轿车 * @author Administrator * */ 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 no, String brand,String type) { super(no, brand); this.type=type; } @Override public int calRent(int days) { // int price=0; if("豪车".equals(this.type)) { price = days*800; }else if("普通车".equals(this.type)) { price = days*500; } return price; } }
-
操作类-customer类
/** * 操作类 * @author Administrator * */ public class Customer { private String name;//顾客姓名 private int days; public int getDays() { return days; } public void setDays(int days) { this.days = days; } public Customer() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Customer(String name) { this.name=name; } public int calTotalRent(MotoVehicle[] motos, int days) { this.days=days; int total=0; for (int i = 0; i < motos.length; i++) { if(motos[i]!=null) { total+=motos[i].calRent(days); } } return total; } }
-
测试
public class Test { public static void main(String[] args) { int days;//天数 int totalRent;//总租金 Bus bus1=new Bus("SA123", "江铃", 15); Bus bus2=new Bus("SA234", "金杯", 40); Car car1=new Car("Sv555", "宝马700", "豪车"); Car car2=new Car("Sv666", "大众朗逸", "普通车"); MotoVehicle motos[]=new MotoVehicle[5]; motos[0]=bus1; motos[1]=bus2; motos[2]=car1; motos[3]=car2; Customer customer = new Customer("顾客狗剩"); totalRent=customer.calTotalRent(motos,8); System.out.println("**********订单************"); for (MotoVehicle motoVehicle : motos) { if(motoVehicle!=null) { System.out.println(motoVehicle.getNo()+"\t"+motoVehicle.getBrand()); } } System.out.println("租赁信息:\n租赁姓名:"+customer.getName() +"\t\n天数:"+customer.getDays() +"\t\n租金:"+totalRent); } }
-
结果
**********订单************ SA123 江铃 SA234 金杯 Sv555 宝马700 Sv666 大众朗逸 租赁信息: 租赁姓名:顾客狗剩 天数:8 租金:28800
4.总结
- 多态的前提是在继承关系下,子类对父类的方法进行重写
- 多态的实现增强了代码的扩展性,让java的应用更加多元化