9.oop之多态

多态

1. 定义

  • 同一个引用类型,使用不同的实例而执行的操作,实现多种形态。

  • 创建一个对象以父类类型接收,因创建的实例不同,而表现出不同的形态,多态一定要在继承关系下的方法重写的情况下才能实现

2.多态有两种体现方式

2.1、使用父类作为方法的形参实现多态

示例:通过食堂给不同的人打饭,方式和价格都不同

  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();
    
    }
    
  2. 子类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("这是学生的特有方法");
    	}
    
    }
    
  3. 子类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("这是老师的特有方法");
    	}
    }
    
  4. 子类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("这是校长的特有方法");
    	}
    }
    
  5. 实现需求的类-食堂类

    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();
    		}		
    	}
    }
    
  6. 测试类

    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);	
    		
    	}
    }
    
  7. 结果

    学生去食堂吃饭
    姓名:张三	年龄:20	性别:男	价格:15.0
    这是学生的特有方法
    老师吃小灶
    姓名:李四	年龄:30	性别:男	价格:25.0
    这是老师的特有方法
    校长,秘书喂饭!
    姓名:王五	年龄:40	性别:男	价格:0.0
    这是校长的特有方法
    

2.2、使用父类作为方法的返回值实现多态

示例:通过选择不同的职业,食堂的价格不同

  1. 食堂类

    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;
    	}
    }
    
  2. 测试类

    public class Test {
    	public static void main(String[] args) {
    		
    		FoodRoom fr = new FoodRoom();
    		
    		fr.dafan(fr.choice("李四",30,"男"));	
    	}
    }
    
  3. 结果

    请选择职业:1.学生2.老师3.校长
    1
    学生去食堂吃饭
    姓名:李四	年龄:30	性别:男	价格:20.0
    这是学生的特有方法
    

2.3、示例3

以上面的的基础加上吃饭天数,计算所有人要交的总价:

  1. 所有的父类,子类都加上天数

    private int day;
    
  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,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;
    	}
    }
    
  3. 测试类

    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);
    		
    	}
    }
    
  4. 结果

    学生去食堂吃饭
    总价:120.0
    老师吃小灶
    总价:125.0
    老师吃小灶
    总价:125.0
    校长,秘书喂饭!
    总价:0.0
    所有人的总价370.0
    

3.案例:汽车租赁系统

目的:通过顾客选择不同的汽车租赁不同的天数计算应该交多少钱

  1. 父类-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);
    
    }
    
  2. 子类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;
    		}
    	}
    
    }
    
  3. 子类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;
    	}
    }
    
  4. 操作类-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;
    	}
    
    }
    
  5. 测试

    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);
    	}
    
    }
    
  6. 结果

    **********订单************
    SA123	江铃
    SA234	金杯
    Sv555	宝马700
    Sv666	大众朗逸
    租赁信息:
    租赁姓名:顾客狗剩	
    天数:8	
    租金:28800
    

4.总结

  1. 多态的前提是在继承关系下,子类对父类的方法进行重写
  2. 多态的实现增强了代码的扩展性,让java的应用更加多元化
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值