栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java多态

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java多态


title: 多态
date: 2021-10-29 14:19:03
tags: java笔记

#多态笔记

面向对象多态 先来看一个问题 首先,使用现有技术解决。

仅展示部分代码

package com.hspedu.poly_.poly2;

public class Master {
    //主人名称
    private String name;
    public Master(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    //完成主任给小狗 喂食 骨头
    public void feed(Dog dog, Food food) {
        System.out.println("主人" + name + "给 " + dog.getName() + "喂食" + food.getName());
    }
}
package com.hspedu.poly_.poly2;

public class Poly2 {
    public static void main(String[] args) {
        Master tom = new Master("tom");
        Dog dog = new Dog("大黄");
        Bone bone = new Bone("大骨棒");
        tom.feed(dog,bone);
        //现在我还需要一个xxx喂猫吃鱼的方法 该如何实现呢
        //难道我需要再写一完成给小猫喂食的方法吗?
    }
}

像下面这样
    public void feed(Cat cat,Fish fish){ //构成方法重载
        System.out.println("主人" + name + "给 " + cat.getName() + "喂食" + fish.getName());
    }

    // 方法调用
        Master bob = new Master("bob");
        Cat cat = new Cat("汤姆");
        Fish fish = new Fish("鱼");
        bob.feed(cat,fish);

这样的确可以实现此需求,可当我们假设有几百个动物需要喂,难道写几百个吗?

此时问题就暴露出来了:代码的复用性不高,而且不利于代码维护

解决方案:

​ 引出多态机制:方法或者对象有多种形态。是面向对象的三大特征,多态是建立在封装和继承基础之上的。

  • 方法的多态:重写和重载体现多态

    public class PloyMethod {
        public static void main(String[] args) {
        //方法重载体现多态
            //我们通过不同的参数去调用sum方法,就会去调用不同的方法,因此sum就是多态的体现
            A a = new A();
            System.out.println(a.sum(10,20));
            System.out.println(a.sum(10,20,30));
    
            // 方法重写体现多态  方法名相同,但是只调用自己类的say()方法
            B b = new B();
            a.say();
            b.say();
        }
    }
    
  • 对象的多态 (核心,困难,重点)

    • 一个对象的编译类型和运行类型可以不一致

    • 编译类型在定义对象时,就确定了,不能够改变

    • 运行类型是可以变化的

            //animal 编译类型 Animal 运行类型:Dog
              Animal animal = new Dog();
              animal.cry();
      
              animal = new Cat();
              animal.cry();
      
    • 编译类型看等号左边,运行类型看等号右边

此时我们再回过头来解决主人喂食问题
    public void feed(Animal animal, Food food) {
        System.out.println("主人" + name + "在学校里给" + animal.getName() + "喂食" + food.getName());

    }
多态注意事项和细节讨论

多态的前提是:两个对象类存在继承关系

多态的向上转型:

Animal animal = new Dog();
animal.cry() //找运行类型cry()

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

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

特点:

  • 编译类看左边 Animal,运行类型看右边 Dog()
  • 可以调用父类中的所有成员(需要遵守访问权限)
  • 不能调用子类中的特有成员(即子类中特有的方法)
  • 因为编译类型是animal 所以他根本不知道子类方法是谁 所以无法调用
public class T {
    public static void main(String[] args) {
        AA aa = new BB();
        aa.test();
        aa.pp()  // ! 这里会报错 无法调用
    }
}

class AA{
    public void test(){
        System.out.println("ok");
    }
}

class BB extends AA{
    public void pp(){
        System.out.println("你好");
    }
}
  • 最终运行效果看子类的具体实现

多态的向下转型:

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

  •  public class T {
         public static void main(String[] args) {
             AA aa = new BB();
             //子类类型 引用名 = (子类类型)父类引用
             //bb 原来指向的就是aa对象 才可以向下转型
             BB bb = (BB) aa;
             bb.pp();
         }
     }
     
     class AA{
         public void test(){
             System.out.println("ok");
         }
     }
     class BB extends AA{
         public void pp(){
             System.out.println("你好");
         }
     }z
    
  • 只能强转父类的引用,不能强转父类的对象

  • 要求父类的引用必须指向的是当前目标类型的对象

  • 当向下转型后可以调用子类类型中的所有成员

属性不存在重写之说

package com.hspedu;

public class PolyDetail02 {
    public static void main(String[] args) {
      //属性没有重写之说,属性的值看编译类型
        base base = new Sub(); //向上转型
        System.out.println(base.count); //直接看编译类型 10
    }
}
class base{
    int count = 10;
}
class Sub extends base{
    int count = 20;
}

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/673118.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号