Java SE 多态

1、多态

  1. 方法的多态

    //方法重载体现多态
    A a = new A();
    //这里我们传入不同的参数,就会调用不同sum方法
    System.out.println(a.sum(10,20));
    System.out.println(a.sum(10,20,30));
    //方法重写体现多态
    
  2. 对象的多态

    • 一个对象的编译类型和运行类型可以不一致
    • 编译类型在定义对象时,就确定了,不能改变
    • 运行类型是可以变化的
    • 编译类型看定义时 = 号 的左边,运行类型看 = 号的右边
    Animal animal = new Dog();//animal编译类型是Animal,运行类型是Dog
    animal = new Cat(); //animal 的运行类型变成了 Cat,编译类型仍然是 Animal
    
  3. 多态的向上转型

    • 本质:父类的引用指向了子类的对象

    • 语法:父类类型 引用名 = new 子类类型();

    • 特点:编译类型看左边,运行类型看右边。

      ​ 可以调用父类中的所有成员(须遵循访问权限)

      ​ 不能调用子类中特有的成员

      最终运行效果看子类(运行类型)的具体实现,

      ​ 即调用方法时,按照从子类开始查找方法,然后调用,规则按方法的调用规则一致

      ​ (从子类找,子类有,则调用,子类无,则在父类找,父类有,并可以调用,则调用,父类无,从祖父类找,祖父类 有,并可以调用,则调用,祖父类无,从Object类找) 如果查找方法的过程中,找到了,但是不能访问,则报错

  4. 多态的向下转型

    • 语法:子类类型 引用名 = (子类类型)父类引用;
    • 只能强转父类的引用,不能强转父类的对象
    • 要求父类的引用必须指向的是当前目标类型的对象
    • 当向下转型后,可以调用子类类型中所有的成员
    Animal animal = new Cat();
    Cat cat = (Cat) animal;
    
  5. 属性没有重写之说!属性的值看编译类型

  6. instanceOf 比较操作符,用于判断对象的运行类型是否为XX类型或XX类型的子类型

  • System.out.println(aa instanceof AA); // true
  1. 属性看编译类型,方法看运行类型

  2. Java的动态绑定机制

    • 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定

      (子类中没有get方法,调用了父类的get方法,但是父类的get方法中又有一个say方法,这个say方法子类也有,则这个时候调用 子类的say方法)

    • 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用

  3. 多态数组:数组的定义类型为父类类型,里面保存的实际元素类型为子类类型

    public class PloyArray {
        public static void main(String[] args){
    
            Person[] person = new Person[5];
            person[0] = new Person("jack",20);
            person[1] = new Student("mary",18,100);
            person[2] = new Student("smith",19,30.1);
            person[3] = new Teacher("scott",30,20000);
            person[4] = new Teacher("king",50,25000);
    
            //循环遍历多态数组,调用say
            for (int i = 0; i < person.length; i++) {
                //person[i] 编译类型是 Person ,运行类型是根据实际情况由JVM来判断
                System.out.println(person[i].say()); //动态绑定机制
                //类型判断 + 向下转型
                if (person[i] instanceof Student){//判断person[i] 的运行类型是不是Student
                    Student student = (Student)person[i];//向下转型
                    student.study();
                }else if(person[i] instanceof Teacher){
                   ((Teacher)person[i]).teach();
                }else if(person[i] instanceof Person){
    
                }else{
                    System.out.println("你的类型有误,请自己检查...");
                }
            }
    
        }
    }
    
    public class Person { //父类
        private String name;
        private int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String say(){ //返回名字和年龄
            return name + "\t" + age;
        }
    }
    
    public class Student extends Person{
        private double score;
    
        public Student(String name, int age, double score) {
            super(name, age);
            this.score = score;
        }
    
        public double getScore() {
            return score;
        }
    
        public void setScore(double score) {
            this.score = score;
        }
    
        //重写父类的say方法
        @Override
        public String say() {
            return  "学生 " + super.say() + " score =" + score;
        }
    
        //特有方法
        public void study(){
            System.out.println("学生 " + getName() + "正在学习...");
        }
    }
    
    public class Teacher extends Person{
        private double salary;
    
        public Teacher(String name, int age, double salary) {
            super(name, age);
            this.salary = salary;
        }
    
        public double getSalary() {
            return salary;
        }
    
        public void setSalary(double salary) {
            this.salary = salary;
        }
    
        //重写父类的say方法
        @Override
        public String say() {
            return "老师 " + super.say() + " salary =" + salary;
        }
    
        //特有方法
        public void teach(){
            System.out.println("老师 " + getName() + "正在授课...");
        }
    }
    
    /*
    运行结果
    jack	20
    学生 mary	18 score =100.0
    学生 mary正在学习...
    学生 smith	19 score =30.1
    学生 smith正在学习...
    老师 scott	30 salary =20000.0
    老师 scott正在授课...
    老师 king	50 salary =25000.0
    老师 king正在授课...
    */
    
  4. 多态参数:方法定义的形参类型为父类类型,实参类型允许为子类类型

    public class PloyParameter {
        public static void main(String[] args) {
            Worker tom = new Worker("tom", 2500);
            Manager milan = new Manager("milan", 5000, 200000);
            PloyParameter ployParameter = new PloyParameter();
            
            ployParameter.showEmpAnnual(tom);
            ployParameter.showEmpAnnual(milan);
    
            ployParameter.testWork(tom);
            ployParameter.testWork(milan);
    
        }
        
        public void showEmpAnnual(Employee e) { //形式参数为父类类型
            System.out.println(e.getAnnual());
        }
        
        public void testWork(Employee e) {
            if (e instanceof Worker) {
                ((Worker) e).work(); //有向下转型
            }else if(e instanceof Manager) {
                ((Manager) e).manager(); //有向下转型
            }else {
                System.out.println("不做处理");
            }
        }
    }
    
    
    public class Employee { //父类
        private String name;
        private double salary; //月工资
    
        public Employee(String name, double salary) {
            this.name = name;
            this.salary = salary;
        }
    
        //得到年工资的方法
        public double getAnnual() {
            return 12 * salary;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public double getSalary() {
            return salary;
        }
    
        public void setSalary(double salary) {
            this.salary = salary;
        }
    
    }
    
    public class Worker extends Employee{
        public Worker(String name, double salary) {
            super(name, salary);
        }
        public void work() {
            System.out.println("普通员工" + getName() + "is working");
        }
    
        @Override
        public double getAnnual() { //普通员工没有其他收入,则直接调用父类方法
            return super.getAnnual();
        }
    }
    
    public class Manager extends Employee{
    
        private double bonus;
    
        public Manager(String name, double salary, double bonus) {
            super(name, salary);
            this.bonus = bonus;
        }
    
        public double getBonus() {
            return bonus;
        }
    
        public void setBonus(double bonus) {
            this.bonus = bonus;
        }
    
        public void manager() {
            System.out.println("经理" + getName() + "is managing");
        }
    
        //重写获取年薪的方法
        @Override
        public double getAnnual() {
            return super.getAnnual() + bonus;
        }
    }
    
    /*
    运行结果
    30000.0
    260000.0
    普通员工tomis working
    经理milanis managing
    */
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值