我在VScode学Java多态(Java多态、instanceof)

Java的多态(Polymorphism)是面向对象编程中的一种特性,它允许不同的对象能够以统一的方式进行访问和操作。
	它允许一个类的实例在运行时表现出多种形态。
Java多态的实现主要依赖于两个基本概念:继承和方法重写。

在Java中,一个子类可以继承父类的方法,并且可以通过重写这些方法来实现自己的特定行为。当我们创建一个对象时,它可以指向自身的类类型,也可以指向任何父类或者实现的接口类型。这就是Java多态性的核心思想:一个对象具有多种外观和行为,这取决于使用它的上下文。

Java多态的好处是可以提高代码的重用性和可维护性,使得代码更加灵活和可扩展。例如,一个方法可以接受一个基类(如Object)作为参数,然后在运行时传入一个子类的实例,这样就可以处理各种不同的对象类型,而无需重写这个方法。

文章目录

  • 在Java中,多态性的实现方式有两种:
      • 表现出多态度的过程:
        • 简要说明:`父类类型` `类型名称` `=` `子类对象`
        • 详细:
    • Java中使用多态的时机通常是在面向对象编程的场景中,特别是在以下情况下比较合适:
    • Java要实现多态性,需要以下几个要点:
      • 0.其他:
      • 1. **继承关系(创建父类和子类):
      • 2. **方法重写(Override):**
      • 3. **父类引用和子类对象:**
      • 4. **运行时绑定(Runtime Polymorphism):**
      • 5. **使用抽象类或接口(可选):**
      • 多态调用成员的特点
  • instanceof 匹配判断成功后将对象强制转换为指定的类
      • 方式壹
          • 代码1:仅仅判断是不是某类
          • 代码2: 匹配后强转
      • 方拾贰:条件判断中同时进行类型检查和类型转换
          • 举例代码:

父类引用引用一个具有子类身份信息的对象时,就创建了一个多态关系的实现效果。

在Java中,多态性的实现方式有两种:

Parent obj = new Child();
obj.show(); // 调用子类的方法

  1. 编译时多态:也称为静态多态,通过方法的重载实现。方法重载是指在一个类中定义多个同名的方法,但参数列表不同,编译器会根据传入的参数类型来选择调用哪个方法。

  2. 运行时多态:也称为动态多态,通过方法的重写实现。方法重写是指子类重新定义了父类中具有相同名称和参数列表的方法,子类对象在运行时会根据具体的对象类型来调用对应的方法。

运行时多态性的实现需要满足以下条件:

  • 存在继承关系:子类继承自父类。
  • 存在方法重写:子类重写了父类的方法。
  • 父类引用指向子类对象:通过父类的引用指向子类的对象,在运行时会根据实际对象的类型调用相应的方法。

表现出多态度的过程:

多态性的优点在于它增加了代码的灵活性和可扩展性,使得代码更易于维护和重用。

简要说明:父类类型 类型名称 = 子类对象

详细:

  1. 父类和子类关系的建立:

    class Parent {
        void show() {
            System.out.println("Parent's show method");
        }
    }
    
    class Child extends Parent {
        void show() {
            System.out.println("Child's show method");
        }
    }
    
  2. 使用多态的情况:

    Parent obj1 = new Parent();
    Parent obj2 = new Child();
    
    obj1.show(); // 调用父类的方法
    obj2.show(); // 调用子类的方法
    
  3. 方法重写(Override):

    @Override
    void show() {
        System.out.println("Child's overridden show method");
    }
    
  4. 父类引用调用子类方法:

    Parent obj = new Child();
    obj.show(); // 调用子类的方法
    

Java中使用多态的时机通常是在面向对象编程的场景中,特别是在以下情况下比较合适:

  1. 继承关系:当有多个类存在继承关系时,可以通过多态来处理它们的对象,从而实现更灵活的代码结构和简化代码逻辑。

  2. 方法的参数:如果一个方法需要接收不同类型的对象,并对它们进行相似的操作,使用多态可以使代码更加通用和易于扩展。

  3. 方法的返回值:当方法返回类型是基类或接口类型,但实际返回的是派生类的实例,可以使用多态来实现。

  4. 集合的使用:在使用集合(如List、Set、Map)时,可以使用多态来存储不同类型的对象,并且通过统一的接口来进行操作。

总的来说,多态使代码更加灵活、可维护性更高,能够提高代码的重用性和扩展性。

Java要实现多态性,需要以下几个要点:

0.其他:

  1. 向上转型:将子类对象赋值给父类引用。这样做可以实现多态性,但只能调用父类中定义的方法。
  2. 向下转型:将父类引用转换为子类对象。需要使用强制类型转换符进行转换。但需要注意的是,向下转型可能会引发ClassCastException异常,因此在转型之前需要进行类型检查(使用instanceof)。

1. **继承关系(创建父类和子类):

** 首先,你需要设计一个父类(基类),其中包含一些通用属性和方法。然后,创建一个或多个子类(派生类),它们继承了父类的属性和方法,并可以添加自己的特定属性和方法。

class Shape {
    void draw() {
        System.out.println("Drawing a shape");
    }
}

class Circle extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing a circle");
    }
}

class Rectangle extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing a rectangle");
    }
}

2. 方法重写(Override):

在子类中,你可以使用@Override注解来重写父类的方法。确保重写的方法具有相同的方法签名(名称、参数列表和返回类型),以便在多态性中起作用。

3. 父类引用和子类对象:

’使用父类的引用变量来引用子类的对象,这是实现多态性的关键。这允许你在编码时保持灵活性,可以在运行时决定调用哪个类的方法。

Shape myShape1 = new Circle();//`Shape` 是父类引用,而 `new Circle();` 是子类对象。
Shape myShape2 = new Rectangle();

myShape1.draw(); // 输出:Drawing a circle
myShape2.draw(); // 输出:Drawing a rectangle

多态性允许我们使用父类的引用来引用子类的对象,这是因为子类对象是可以赋值给父类引用的。这有助于实现代码的灵活性和可扩展性。

Shape myShape1 = new Circle(); 这行代码中,我们创建了一个 Circle 类的对象,并将其赋值给 Shape类型的引用变量 myShape1。由于 Circle Shape 的子类,这种赋值是合法的。这意味着虽然myShape1的类型是 Shape,但它指向的实际上是一个 Circle 类型的对象。

通过这种方式,我们可以使用通用的 Shape 引用来引用不同的具体形状对象,从而实现了多态性和继承的概念。这种设计模式允许我们在代码中以一种更抽象的方式操作对象,同时保留了具体对象的特定功能。

4. 运行时绑定(Runtime Polymorphism):

当通过父类引用调用方法时,Java会在运行时动态地确定实际调用的方法,这称为运行时绑定。这意味着你可以在不同的上下文中使用相同的方法调用,但实际执行的是不同子类的方法。

5. 使用抽象类或接口(可选):

如果你希望定义一组共享的方法签名,可以使用抽象类或接口。抽象类可以提供部分实现,而接口则强制实现所有方法。这使得多态性更加灵活,可以在不同类之间共享更多的行为。

interface Sound {
    void makeSound();
}

class Dog implements Sound {
    @Override
    public void makeSound() {
        System.out.println("Dog barks");
    }
}

class Cat implements Sound {
    @Override
    public void makeSound() {
        System.out.println("Cat meows");
    }
}

综上所述,实现多态性需要创建继承关系、重写方法、使用父类引用和子类对象、运行时绑定以及可能的抽象类或接口。这些概念共同使多态性成为面向对象编程中的强大特性,提高了代码的灵活性和可维护性。

多态调用成员的特点

变量调用:编译看左边,运行也看左边
方法调用:编译看左边,运行看右边

  1. 变量调用成员时,编译时会根据变量的声明类型(左边)来确定可访问的成员,运行时也会使用变量的实际类型(左边)来确定实际执行的代码。

编译时看左边: 在编译阶段,编译器会检查父类中是否存在被调用的成员变量。如果存在,编译通过;如果不存在,编译失败。
运行时也看左边: 在运行阶段,程序实际获取的是左边父类中的成员变量的值,而不考虑实际对象的类型。

  1. 方法调用时,编译时会根据变量的声明类型(左边)来确定可调用的方法,但在运行时会根据实际对象的类型(右边)来决定实际执行的方法。

编译时看左边: 在编译阶段,编译器会检查变量的声明类型(左边)来确定可调用的方法。如果左边的类型没有声明被调用的方法,编译会报错,即使实际对象具有相应的方法。
运行时看右边: 在运行阶段,方法调用会根据实际对象的类型(右边)来决定实际执行的方法。即使使用父类的引用,程序也会根据实际对象的类型来调用相应的方法,这被称为动态方法分派。

这 种行为允许你在运行时通过替换对象实例来实现不同的行为,这是面向对象编程中多态性的一个关键概念。

class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat meows");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myAnimal1 = new Dog();  // 编译看左边,运行也看左边
        Animal myAnimal2 = new Cat();  // 编译看左边,运行也看左边

        myAnimal1.makeSound();  // 编译看左边,运行看右边 ("Dog barks")
        myAnimal2.makeSound();  // 编译看左边,运行看右边 ("Cat meows")
    }
}

在这里插入图片描述

instanceof 匹配判断成功后将对象强制转换为指定的类

使用 instanceof 进行类型检查和强制类型转换时,应该确保类型转换是安全的,即要确保对象的实际类型与你尝试转换的类型是相符的。如果类型不匹配,会在运行时抛出 ClassCastException 异常。

方式壹

if (object instanceof MyClass) {
    MyClass myObject = (MyClass) object;
    // 此时可以使用 myObject 来访问 MyClass 特有的方法和属性
}

在这里,object 是要检查的对象,MyClass 是要检查的类名。如果 object 是 MyClass 类的实例或者其派生类的实例,条件就会为真,代码块会被执行。`

代码1:仅仅判断是不是某类
class ParentClass {
    // Contents of the parent class
}

class ChildClass1 extends ParentClass {
    // Contents of the first child class
}

class ChildClass2 extends ParentClass {
    // Contents of the second child class
}

public class Main {
    public static void main(String[] args) {
        ParentClass obj = new ParentClass(); // This can be an instance of any class
        
        if (obj instanceof ChildClass1) {
            System.out.println("obj is an instance of ChildClass1");
        } else if (obj instanceof ChildClass2) {
            System.out.println("obj is an instance of ChildClass2");
        } else {
            System.out.println("obj is not an instance of ChildClass1 or ChildClass2");
        }
    }
}

在这个示例中,我们首先创建了一个 ParentClass 的实例,然后使用 instanceof 运算符检查它是否是 ChildClass1 或 ChildClass2 的实例。如果都不是,就输出相应的提示信息。

请注意,这个示例中的类和实例是一种简化,实际情况可能会更加复杂。不过,基本的 instanceof 使用方式和逻辑与这个示例类似。

代码2: 匹配后强转
class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    public void makeSound() {
        System.out.println("Dog barks");
    }
    
    public void fetch() {
        System.out.println("Dog fetches the ball");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myAnimal = new Dog();

        if (myAnimal instanceof Dog) {
            Dog myDog = (Dog) myAnimal;
            myDog.fetch(); // 可以调用 Dog 特有的方法
        }

        myAnimal.makeSound(); // 输出:Dog barks
    }
}

方拾贰:条件判断中同时进行类型检查和类型转换

if (object instanceof MyClass myObject) {
    
    // 此时可以使用 myObject 来访问 MyClass 特有的方法和属性
}
举例代码:
class MyClass {
    public void myMethod() {
        System.out.println("MyClass method");
    }
}

public class Main {
    public static void main(String[] args) {
        Object object = new MyClass();

        if (object instanceof MyClass myObject) {
            myObject.myMethod(); // 可以直接使用 myObject 调用 MyClass 的方法
        }
    }
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/66716.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DC-7靶机

DC-7靶机地址 同样的,把靶机跟kali放在同一网段,(NAT模式) 主机发现 arp-scan -l端口扫描 nmap -A -T4 -p- 192.168.80.13922端口开始,80端口开启 浏览器先访问一下靶机的80端口 熟悉的Drupal站点 先爆破一下目录…

http相关知识点

文章目录 长链接http周边会话保持方案1方案2 基本工具postmanFiddlerFiddler的原理 长链接 一张网页实际上可能会有多种元素组成,这也就说明了网页需要多次的http请求。可由于http是基于TCP的,而TCP创建链接是有代价的,因此频繁的创建链接会…

【Spring】Spring AOP 初识及实现原理解析

博主简介:想进大厂的打工人博主主页:xyk:所属专栏: JavaEE进阶 目录 文章目录 一、初识AOP 1.1 什么是AOP? 1.2 AOP的组成 1.2.1 切面(Aspect) 1.2.2 切点(Pointcut) 1.2.3 连接点&…

菲律宾的区块链和NFT市场调研

菲律宾的区块链和NFT市场调研 基本介绍 参考: https://zh.wikipedia.org/wiki/%E8%8F%B2%E5%BE%8B%E5%AE%BE zheng治制度:Zongtong议会制 现任Zongtong: 小费迪南德马科斯, 是独裁者费迪南德马科斯之子,人称“小马科斯” 官方语言…

使用ResponseBodyAdvice做分页处理

目录 父pom文件 pom文件 配置文件 MyResponseBodyAdvice ResponseDto MyBatisConfig UsersController UsersMapper UserMapper.xml 结果 父pom文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/PO…

【计算机视觉 | Kaggle】保姆级教程:入门 Kaggle 的步骤详细介绍

文章目录 一、Overview二、Evaluation三、Timeline四、Code Requirements五、Data5.1 数据的可视化5.2 文件 六、Discussion七、Code 一、Overview 当进入到一场比赛的 Overview 页面后&#xff0c;先读完 Description&#xff0c;了解比赛讲了一件什么事情。 我们以一场比赛…

鸿鹄工程项目管理系统em Spring Cloud+Spring Boot+前后端分离构建工程项目管理系统em

​ Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目…

成功解决Linux下中文乱码问题,CentOS7设置系统字符编码

在linux中&#xff0c;可以使用以下命令查看当前系统的字符编码&#xff1a; echo $LANG 如果不是UTF-8&#xff0c;就会出现中文乱码现象! 解决办法&#xff1a;设置字符编码环境变量为utf-8 1. 打开 ~/.bashrc 或 ~/.bash_profile 文件 vi ~/.bashrc 或 vi ~/.bash_prof…

力扣 474. 一和零

题目来源&#xff1a;https://leetcode.cn/problems/ones-and-zeroes/description/ C题解&#xff1a;本题其实是01背包问题&#xff01;只不过这个背包有两个维度&#xff0c;一个是m 一个是n&#xff0c;而不同长度的字符串就是不同大小的待装物品。动规五部曲&#xff1a; …

《高性能MySQL》——查询性能优化(笔记)

文章目录 六、查询性能优化6.1 查询为什么会慢6.2 慢查询基础&#xff1a;优化数据访问6.2.1 是否向数据库请求了不需要的数据查询不需要的记录多表关联时返回全部列总是取出全部列重复查询相同的数据 6.2.2 MySQL 是否在扫描额外的记录响应时间扫描的行数与返回的行数扫描的行…

云计算技术——多GPU渲染的云渲染服务

多GPU渲染的云渲染服务&#xff0c;是一种利用云计算技术&#xff0c;将多个图形处理器&#xff08;GPU&#xff09;集成在一起&#xff0c;为用户提供高效、便捷、低成本的渲染解决方案的服务。本文将从多GPU渲染的概念、优势、应用场景&#xff0c;云渲染服务的特点、优势&am…

使用 PowerShell 将 Excel 中的每个工作表单独另存为独立的文件

导语&#xff1a;在日常工作中&#xff0c;我们经常需要处理 Excel 文件。本文介绍了如何使用 PowerShell 脚本将一个 Excel 文件中的每个工作表单独另存为独立的 Excel 文件&#xff0c;以提高工作效率。 1. 准备工作 在开始之前&#xff0c;请确保已经安装了 Microsoft Exc…

领航优配:沪指震荡涨0.47%,保险、券商板块强势,互联金融概念活跃

4日早盘&#xff0c;两市股指高开高走&#xff0c;沪指一度涨逾1%打破3300点&#xff0c;随后涨幅有所收窄&#xff1b;两市半日成交超6000亿元&#xff0c;北向资金小幅净流入。 截至午间收盘&#xff0c;沪指涨0.47%报3295.91点&#xff0c;深成指涨0.67%&#xff0c;创业板指…

【ARM Cache 系列文章 9 番外篇 -- ARMv9 系列 Core 介绍】

文章目录 ARMv9 系列CoreARM Cortex-A510 介绍ARM Cortex-A715ARM Cortex-A720 ARMv9 系列Core 2021年5月Arm公布了其最新3款CPU和3款GPU核心设计&#xff0c;三款新CPU分别是旗舰核心Cortex-X2、高性能核心Cortex-A710、高能效核心Cortex-A510 CPU&#xff0c;三款新GPU核心则…

【office】world设置标题

这里写目录标题 一、整理样式库二、设置标题编号三、设置标题其它信息1.设置 标题 1a.设置字体b.设置边框c.设置段落 2.设置 标题 2a.设置字体b.设置边框 3.设置 标题 3a.设置字体b.设置边框 4.设置 标题 4a.设置字体 5.设置 标题 5a.设置字体 一、整理样式库 1.选择“开始” …

华为智选首款纯电轿跑“LUXEED”能大卖吗?

监制 | 何玺 排版 | 叶媛 华为智选纯电轿跑来袭&#xff01; 8月7日&#xff0c;华为常务董事余承东在社交媒体上发文&#xff0c;宣布华为智选即将推出首款“突破想象”的纯电轿跑车。 01 华为智选首款纯电轿跑来袭 余承东的发文引起了极大关注&#xff0c;在各大媒体的报…

lc137. 只出现一次的数字 II

数组排序&#xff0c;既和前不一样又和后不一样的就是唯一的一个 public static int numberOnce(int[] nums) {Arrays.sort(nums);if (nums.length > 2 && nums[0] ! nums[1]) {//避免只有一个元素的数组return nums[0];}if (nums.length > 2 && nums[nu…

华秋亮相2023世界汽车制造技术暨智能装备博览会,推动汽车产业快速发展

洞悉全球汽车产业格局&#xff0c;前瞻业界未来趋势。2023年7月27日-30日&#xff0c;时隔三年&#xff0c;重聚武汉国际博览中心&#xff0c;2023世界汽车制造技术暨智能装备博览会盛大开幕。深耕汽车行业多年的世界汽车制造技术暨智能装备博览会&#xff0c;掀起行业热点新高…

一文详解 DolphinDB SQL 标准化

为了提升用户体验&#xff0c;降低用户学习成本和脚本迁移复杂度&#xff0c;自 1.30.17 / 2.00.5 版本开始&#xff0c;DolphinDB 逐步支持了标准化 SQL 的书写方法&#xff1b;并于 1.30.22 / 2.00.10 版本起&#xff0c;对标准 SQL 的常用语法和关键字实现了兼容。 1. 与标…

前端下载文件

前端可以通过使用 JavaScript中的 fetch 或者 XMLHttpRequest 来下载文件&#xff1b; 使用fetch进行文件下载&#xff1b; fetch(http://example.com/file.pdf).then(response > response.blob()).then(blob > {// 创建一个临时的URL对象const url window.URL.create…