IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java学习笔记——多态(实例详解) -> 正文阅读

[Java知识库]Java学习笔记——多态(实例详解)

多态是某一事物,在不同时刻体现出来的不同的状态

就比如猫,狗,狼都是动物,我们可以说猫是动物,说狗是动物
但我们不能说动物是猫,动物是狼。也不能说猫是狗,或者狗是狼。
上面这几点都会在多态中体现出来

多态的前提:

  1. 类之间要有继承的关系
  2. 子类要有对父类方法的重写(不重写也不会报错,但这样体现不出来多态的意义)
  3. 父类的引用变量指向子类对象

下面看一个多态的简单例子

class Animal{
    public void eat(){
        System.out.println("动物要进食");
    }
}

class Cat extends Animal{
    public void eat(){
        System.out.println("猫咪要吃饭");
    }
}

public class Demo1 {
    public static void main(String[] args) {
        //从右往左念,猫咪是动物
        //new Cat()已经创建了一个Cat类的对象,在堆内存之中
        //Animal类的引用变量指向了Cat类的子类对象
        Animal a = new Cat();
        //这里会优先调用子类的重写方法
        a.eat();
    }
}

结果为
在这里插入图片描述
这里需要注意的是,虽然是父类的引用变量,但实际上调用eat()方法时,调用的是子类重写后的eat()方法

如果对重写不了解的话,可以看下面链接里面的博客
继承里面的重写问题

多态访问成员特点
1、成员变量
编译看左边,运行看左边
2、构造方法
创建子类对象的时候,先访问父类的构造方法,先对父类的数据进行初始化
3、成员方法
编译看左边,运行看右边
因为子类的成员方法存在重写,所以运行访问的时候看右边
4、静态的成员方法:
编译看左边,运行看左边
静态的随着类的加载而加载
由于被static修饰的都是与类有关系的,所以它算不上重写
所以,编译的时候看左边,运行访问的时候也看左边

这里的左边指的是父类的引用变量,右边指的是子类的对象
在这里插入图片描述
这个单独看文字比较难懂,所以下面还是要看几个例子
首先是第一条,成员变量,编译看左边,运行看左边

class Animal{
    int num =10;
    public void eat(){
        System.out.println("动物要进食");
    }
}

class Cat extends Animal{
    int num = 20;
    public void eat(){
        System.out.println("猫咪要吃饭");
    }
}

public class Demo1 {
    public static void main(String[] args) {
        Animal a = new Cat();
        System.out.println(a.num);
    }
}

输出结果为 10
编译和运行都看左边的意思是,输出的结果根据父类的属性值来定,而不是子类

然后是第二条,可以看这篇博客的后半部分,关于构造方法调用顺序的详细解释
关于构造方法调用顺序的详细解释

第三条成员方法,编译看左边,运行看右边
例子就用我在这篇博客开头就举了的例子就行
编译看左边的意思是编译过程中看父类中是否有这个方法
运行看右边的意思是运行过程中实际调用的方法是子类中重写后的方法

第四条静态的成员方法

class Animal{
    int num =10;
    public void eat(){
        System.out.println("动物要进食");
    }
    public static void sleep(){
        System.out.println("动物要休息");
    }
}

class Cat extends Animal{
    int num = 20;
    public void eat(){
        System.out.println("猫咪要吃饭");
    }
    public static void sleep(){
        System.out.println("猫咪要睡觉");
    }
}

public class Demo1 {
    public static void main(String[] args) {
        Animal a = new Cat();
        //System.out.println(a.num);
        Animal.sleep();
        Cat.sleep();
    }
}

结果为
在这里插入图片描述
因为是用类名调用,所以都是打印相对应的结果

介绍完多态访问成员的特点后,我们需要思考一个问题,为什么要使用,以及使用多态有什么好处
下面来看这个例子

class Animal{
    public void eat(){
        System.out.println("动物要进食");
    }
    public void sleep(){
        System.out.println("动物要休息");
    }
}

class Cat extends Animal{
    public void eat(){
        System.out.println("猫咪要吃饭");
    }
    public void sleep(){
        System.out.println("猫咪要睡觉");
    }
}

class Dog extends Animal{
    public void eat(){
        System.out.println("狗要啃骨头");
    }
    public void sleep(){
        System.out.println("狗要打盹");
    }
}

public class Demo1 {
    public static void main(String[] args) {
        Cat c = new Cat();
        c.eat();
        c.sleep();
        Dog d = new Dog();
        d.eat();
        d.sleep();
    }
}

这里发现,如果输出猫和狗的实例对象的eat和sleep方法的结果,就需要分别用Cat类的对象c来调用,用Dog类的对象d来调用。这里是因为对象较少,调用的方法也只有eat和sleep两个方法,所以看起来还算简洁。

但如果我要创建十只猫的实例呢?要c1.eat(),c2.sleep()……这样一直调用下去吗?
那如果我不止猫和狗两种动物呢?我还要写狼的类,写豹子的类,写大象的类,都继承Animal类,然后输出这些类的对象调用方法的结果。

这时就会发现,代码的调用方法部分将变得非常冗长,有没有一种办法,可以让我们不需要用实例对象一个一个的调用方法呢?
这时候我们就需要用到多态了。而我们需要做的事情,就是创建对象,并且将对象作为参数传入一个工具类中,工具类里面会定义各种需要调用的方法。

class Animal{
    public void eat(){
        System.out.println("动物要进食");
    }
    public void sleep(){
        System.out.println("动物要休息");
    }
}

class Cat extends Animal{
    public void eat(){
        System.out.println("猫咪要吃饭");
    }
    public void sleep(){
        System.out.println("猫咪要睡觉");
    }
}

class Dog extends Animal{
    public void eat(){
        System.out.println("狗要啃骨头");
    }
    public void sleep(){
        System.out.println("狗要打盹");
    }
}

class Bird extends Animal{
    public void eat(){
        System.out.println("鸟儿吃虫子");
    }
    public void sleep(){
        System.out.println("鸟儿休憩");
    }
}
class AnimalTools {
//private的作用是让外面无法创建AnimalTools类的对象,只能使用这里面的方法
    private AnimalTools() {
    }
    public static void funAnimal(Animal animal){
        animal.eat();
        animal.sleep();
    }
}
public class Demo1 {
    public static void main(String[] args) {
        Cat c = new Cat();
        Dog d = new Dog();
        Bird b = new Bird();
        AnimalTools.funAnimal(c);
        AnimalTools.funAnimal(d);
        AnimalTools.funAnimal(b);
        Cat c2 = new Cat();
        AnimalTools.funAnimal(c2);
    }
}

结果为
在这里插入图片描述

多态的好处:
提高了程序的维护性(由继承保证)
提高了程序的扩展性(由多态保证)

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-29 10:06:28  更:2021-09-29 10:09:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:12:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码