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 Person{

}

class Man extends Person{

}

public class Test{
	public static void main(String[] args){
		Person p1 = new Man();
	}
} 

在上面代码中,定义了两个类,并且Man()类继承了Person()类,“Person p1 = new Man();”,此行代码即为父类的引用指向子类的对象。

多态性的使用前提:

  • 需有类的继承关系
  • 方法的重写
  • 向上转型:在多态中需要将子类的对象赋给父类的引用,只有这样该引用才既能调用父类的方法,又能调用子类的方法。

多态的使用:虚拟方法调用

  1. 子类中定义了与父类同名同参数的方法(即方法的重写),在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。
  2. 有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类中重写父类的方法。
    一句话概括就是:编译,看左边;运行,看右边。
public class Test{
    public static void main(String[] args) {
        Person p1 = new Chinese();
        p1.speak();
        // p1不能调用子类中特有的方法,会报错
        // p1.skin();
        System.out.println("age:" + p1.age);
    }
}

class Person{
    int age = 20;
    private String name;

    public void speak(){
        System.out.println("人可以说话");
    }
}

class Chinese extends Person{
	  
	  int age = 30;
    @Override
    public void speak() {
        System.out.println("中国人说汉语");
    }
	
	 public void skin(){
        System.out.println("黄皮肤");
    }
}

在上面代码中,父类Person()中定义了方法speak(),在子类Chinese()中,重写了此方法。根据前面总结的:编译时看左边,运行时看右边,此时如果我们想要查看“ p1.speak() ”具体调用的是哪个方法(将鼠标放在p1.speak()上,按住Ctrl键,然后点击鼠标),会发现eclipse指向了父类Person()中定义的speak()方法;但是,当我们运行程序时,实际输出的内容是“中国人说汉语”,说明运行时,实际调用的是子类Chinese()中重写的speak()方法。
注意:

  • 对象p1不能调用子类中特有的方法,如代码中的“ skin() ”。
  • 对象的多态性只适用于方法,不适用于属性。
    上述代码运行结果:
    在这里插入图片描述

向下转型

按照上面代码中的写法“ Person p1 = new Chinese(); ”,我们可以调用子类中重写父类的方法,但不能调用子类特有的方法,如果我们想要调用子类特有的方法,就需要用到向下转型(使用强制类型转换)。即

public class Test{
    public static void main(String[] args) {
        Person p1 = new Chinese();
        p1.speak();
        // p1不能调用子类中特有的方法,会报错
        // p1.skin();
        System.out.println("age:" + p1.age);
        System.out.println("-----------------------");
        Chinese c1 = (Chinese)p1;   // 向下转型
        c1.skin();
    }
}

输出结果:
在这里插入图片描述但是,在使用向下转型时,有可能出现ClassCastException的异常,例如:

class American extends Person{
    @Override
    public void speak() {
        System.out.println("美国人说英语");
    }
}

public class Test {
    public static void main(String[] args) {
        Person p1 = new Chinese();
        p1.speak();
        // p1不能调用子类中特有的方法,会报错
        // p1.skin();
        System.out.println("age:" + p1.age);
        System.out.println("-----------------------");
        Chinese c1 = (Chinese)p1;
        c1.skin();

        American a1 = (American)p1;
    }
}

上面代码中,子类American()同样继承了父类Person(),在程序运行时,会在“ American a1 = (American)p1; ”出现异常:
在这里插入图片描述为了避免在向下转型时,出现此异常,我们可以使用instanceof关键字。

instanceof关键字

  1. a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false
  2. 使用情境:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,就不进行向下转型。
  3. 如果a instanceof A返回true,则a instanceof B也返回true。其中,类B是类A的父类。

举例

public class Test {
    public static void main(String[] args) {
        Person p1 = new Chinese();
        p1.speak();
        // p1不能调用子类中特有的方法,会报错
        // p1.skin();
        System.out.println("age:" + p1.age);
        System.out.println("-----------------------");
        Chinese c1 = (Chinese)p1;
        c1.skin();

        Person p2 = new American();
        if(p2 instanceof Chinese){
            System.out.println("p2 is a Chinese");
        }

        if(p2 instanceof American){
            System.out.println("p2 is a American");
        }
    }
}

输出结果:
在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-06 16:04:04  更:2022-04-06 16:06:04 
 
开发: 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/24 8:01:44-

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