首页 > 其他分享 >多态的概念

多态的概念

时间:2024-08-02 11:07:49浏览次数:13  
标签:子类 多态 接口 概念 多态性 方法 public

多态


多态(Polymorphism)是面向对象编程(OOP)的一个核心概念,它指的是同一个接口可以被多个对象以不同的方式实现。多态性使得代码更加灵活,易于扩展和维护。

多态性的类型

  1. 编译时多态(Static Polymorphism)或方法重载(Method Overloading):

    • 这是在编译时期就确定的多态性,通过方法名和参数列表来区分不同的方法。
  2. 运行时多态(Dynamic Polymorphism)或方法重写(Method Overriding):

    • 这是在运行时期确定的多态性,通过对象的实际类型来调用相应的方法。

多态性的特点

  1. 接口一致性:

    • 多态性要求存在一个共同的接口。这意味着不同的类必须有相同名称和参数的方法。
  2. 实现多样性:

    • 尽管接口一致,但每个类可以有自己的方法实现。
  3. 动态绑定:

    • 在运行时,根据对象的实际类型来调用相应的方法,这个过程称为动态绑定或晚期绑定。
  4. 基类引用:

    • 可以使用基类(或接口)的引用来指向派生类的对象。
  5. 提高灵活性:

    • 多态性允许编写不依赖于具体类实现的代码,提高了代码的灵活性和可扩展性。

多态性的实现

  1. 方法重写:

    • 子类重写(Override)基类中的方法,以提供特定的实现。
  2. 抽象类和接口:

    • 使用抽象类和接口来定义方法的签名,然后让不同的类实现这些方法。
  3. 向上转型:

    • 将子类的对象赋值给基类(或接口)的引用,这是实现多态性的常见手段。

多态性的好处

  1. 代码复用:

    • 通过使用基类(或接口)的引用来调用方法,可以在不同的地方重用相同的代码。
  2. 解耦合:

    • 多态性降低了类之间的耦合度,使得系统更加模块化。
  3. 扩展性:

    • 系统可以通过添加新的类来扩展功能,而不需要修改现有的代码。
  4. 易于维护:

    • 当需要修改行为时,只需修改特定的实现类,而不影响使用这些类的代码。
  5. 设计灵活性:

    • 设计者可以在不同的上下文中使用相同的接口,但具有不同的行为。

多态性的示例(Java)

class Animal {
    void makeSound() {
        System.out.println("Some sound");
    }
}

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

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

public class Main {
    public static void main(String[] args) {
        Animal myAnimal = new Dog(); // 向上转型
        myAnimal.makeSound(); // 输出 "Woof woof"

        myAnimal = new Cat(); // 改变引用类型
        myAnimal.makeSound(); // 输出 "Meow meow"
    }
}

在这个示例中,Animal 是一个基类,DogCat 是派生自 Animal 的子类,它们重写了 makeSound 方法。在 Main 类的 main 方法中,Animal 类型的引用 myAnimal 指向了 DogCat 的对象,展示了运行时多态性。

为什么要使用多态(多态的优点)


优点

  1. 代码通用性:

    • 多态允许编写可以在许多不同类型的对象上运行的通用代码,而不需要针对每种类型编写特定代码。
  2. 解耦合:

    • 多态减少了各个组件之间的依赖关系。使用多态,一个组件可以与另一个组件交互,而不需要了解后者的具体实现细节。
  3. 扩展性:

    • 多态支持开闭原则,即软件实体应对扩展开放,对修改关闭。通过多态,可以添加新的对象类型而不必修改现有的代码。
  4. 灵活性和灵活性:

    • 多态提供了更高的灵活性,使得程序能够更容易地适应变化,例如,通过简单地替换对象来改变程序的行为。
  5. 简化复杂系统:

    • 在复杂的系统中,多态可以简化设计,通过统一的接口来管理多样化的对象集合。
  6. 提高代码可维护性:

    • 当需要修改或扩展系统时,多态减少了可能引入的错误,因为修改通常局限于特定的实现类。
  7. 支持设计模式:

    • 许多设计模式,如工厂模式、策略模式、命令模式等,依赖于多态性来实现灵活和可重用的设计。
  8. 易于单元测试:

    • 多态性简化了单元测试,可以通过接口使用模拟对象代替复杂的依赖项,从而更容易地测试代码。
  9. 实现算法的多样性:

    • 多态允许为不同类型的对象实现不同的算法,而保持调用接口的一致性。
  10. 促进专业化:

    • 通过多态,可以创建专业化的子类,每个子类都有其特定的行为,而公共的行为则保留在基类或接口中。
  11. 代码重用:

    • 多态性支持代码重用。通过继承和方法重写,可以在不同的上下文中重用基类代码。
  12. 动态行为:

    • 多态允许对象在运行时改变其行为,这在处理不同类型对象的集合或数组时特别有用。
  13. 简化客户端代码:

    • 客户端代码可以使用基类或接口引用来操作对象,而不需要关心对象的具体类型。
  14. 适应性:

    • 多态性允许程序更容易地适应新的或未知的对象类型,因为程序可以根据对象的实际类型动态地调用适当方法。
  15. 促进面向对象思维:

    • 多态性鼓励开发者从接口和行为的角度思考问题,而不是从具体的类和实现的角度。

多态的分类


多态性在面向对象编程中主要分为两大类:编译时多态(也称为静态多态或方法重载)和运行时多态(也称为动态多态或方法重写)。

1. 编译时多态(Static Polymorphism / Method Overloading)

  • 定义: 编译时多态发生在编译期间,根据方法名和参数列表(参数的类型、数量或顺序)来确定调用哪个方法。

  • 特点:

    • 参数列表不同:可以是参数类型不同、参数个数不同或参数顺序不同。
    • 重载的方法在同一个类中。
    • 编译器在编译时根据方法签名选择正确的方法版本。
  • 示例:

    class Calculator {
        public int add(int a, int b) {
            return a + b;
        }
        
        public double add(double a, double b) {
            return a + b;
        }
    }
    

    这里,add 方法被重载了两次,一次接受两个 int 类型的参数,另一次接受两个 double 类型的参数。

2. 运行时多态(Dynamic Polymorphism / Method Overriding)

  • 定义: 运行时多态发生在运行期间,根据对象的实际类型来确定调用哪个方法。
  • 特点:
    • 子类重写(Override)了父类的方法。
    • 通过父类或接口的引用调用方法,而实际执行的是子类中重写的方法。
    • 需要至少涉及两个类,其中一个是另一个的子类或实现了同一接口。
    • 利用了动态绑定(晚期绑定)机制。
  • 示例:
    class Animal {
        public void sound() {
            System.out.println("Animal makes a sound");
        }
    }
    
    class Dog extends Animal {
        @Override
        public void sound() {
            System.out.println("Dog barks");
        }
    }
    
    public class TestPolymorphism {
        public static void main(String[] args) {
            Animal myAnimal = new Dog(); // 向上转型
            myAnimal.sound(); // 输出 "Dog barks"
        }
    }
    
    在这个例子中,Dog 类重写了 Animal 类的 sound 方法。尽管变量 myAnimal 被声明为 Animal 类型,但由于多态性,实际调用的是 Dog 类的 sound 方法。

多态的机制原理


多态的机制原理的核心概念:

动态绑定(Dynamic Binding)/晚期绑定(Late Binding):

  • 在运行时多态中,方法调用的绑定发生在程序执行时。当通过父类或接口的引用调用一个方法时,Java虚拟机(JVM)查找实际对象的类,确定应该调用哪个方法。

方法表(Method Table):

  • 每个类在加载时,JVM会为它创建一个方法表,其中包含该类所有方法的引用。对于重写的方法,子类的方法表会覆盖父类方法表中的相应条目。

虚函数表(Virtual Method Table):

  • 一些语言实现(如C++)使用虚函数表来实现多态。每个包含虚函数的类都有一个虚函数表,表中包含了虚函数的地址。当通过基类的指针或引用调用虚函数时,程序会查找对象的虚函数表来确定调用哪个函数。

接口:

  • 接口定义了一组方法规范,实现接口的类必须提供这些方法的具体实现。在Java中,接口使用动态绑定来实现多态。

抽象类:

  • 抽象类可以包含抽象方法,这些方法没有具体的实现。子类继承抽象类时,必须提供抽象方法的实现。

向上转型(Upcasting):

  • 将子类的对象赋值给父类或更通用的类型的引用。这是多态性的基础,因为向上转型是安全的,编译器允许这种转型。

方法重写(Method Overriding):

  • 子类提供了与父类中具有相同方法名、返回类型和参数列表的方法,但具有不同的实现。

方法重载(Method Overloading):

  • 一个类中可以有多个相同名字的方法,但参数列表不同。这是编译时多态的基础。

类型信息(Type Information):

  • 在运行时,JVM维护有关对象类型的信息。当发生多态调用时,JVM使用这些信息来确定实际的方法实现。

访问控制:

  • 即使方法被重写,访问控制仍然适用。如果子类中的方法具有较严格的访问控制(如从public变为protected),则在多态调用时可能会受到限制。

运行时多态的示例原理:

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

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

public class Main {
    public static void main(String[] args) {
        Shape shape = new Circle(); // 向上转型
        shape.draw(); // 运行时多态
    }
}

在上述代码中,尽管变量shape被声明为Shape类型,但它实际上指向一个Circle对象。当调用shape.draw()时,JVM在运行时查找Circle类的方法表,找到draw方法的实现,并执行它。这就是动态绑定的工作原理,它允许程序在运行时根据对象的实际类型来调用正确的方法实现。

标签:子类,多态,接口,概念,多态性,方法,public
From: https://www.cnblogs.com/czj03/p/18338323

相关文章

  • 接口和多态的关系
    接口和多态的关系多态性的基础:接口是实现多态性的关键机制之一。通过接口,不同的类可以实现相同的方法,但具体的实现可以各不相同。方法重载:多态性允许同一个方法名在不同的类中有不同的实现。接口定义了这些方法的统一签名,而实现类提供了具体的实现细节。动态绑......
  • 接口的概念
    什么是接口接口(Interface)在面向对象编程(OOP)中是一种定义了一组方法规范的抽象类型。它是一种形式的契约,规定了实现该接口的类必须遵循的一组方法和行为。基本特征抽象性:接口不提供方法的具体实现,只定义方法的签名。多态性:接口允许不同的类以自己的方式实现这些方法,......
  • 抽象类的概念
    什么是抽象在面向对象编程中,"抽象"是一个核心概念,它允许我们专注于对象的基本特征,忽略那些与当前目标无关的细节。以下是“抽象”的两个主要方面:抽象数据类型(AbstractDataType,ADT)抽象数据类型是一种仅通过其行为(方法)和接口(数据结构)来描述的数据类型,而不需要关心具体的实......
  • Linux路径的概念及目录的操作命令 cd、pwd、mkdir、rmdir
    本文主要介绍Linux系统中路径的基本概念以及对目录的基础操作。根目录的概念在Windows操作系统中,是由盘符开始描述路径,如:C:\Programs\abc\或者D:\game\abc\。在Linux操作系统中,则是以目录树的形式展现,所有的文件及目录都是从根目录/开始的,如/home,/etc等,即便是有多......
  • 多态
    多态(Polymorphism)多态(Polymorphism)是面向对象编程中的一个核心概念,它指的是同一种类型的对象在不同的情况下表现出不同的行为。以下是对多态概念的详细解释:一、多态的定义基本定义:多态通俗来说就是多种形态,具体表现为去完成某个行为时,当不同的对象去完成时会产生出不同的状......
  • 多态
    多态1.多态的概念多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作,如下图多态性是对象多种表现形式的体现。现实中,比如我们按下F1键这个动作:如果当前在Flash界面下弹出的就是AS3的帮助文档;如果当前在Word下......
  • Animate基本概念:补间动画
    补间动画是Animate软件中比较重要的组成部分。举例来说,假设第1帧和第20帧是属性关键帧,可以将舞台左侧的一个元件放在第1帧中,然后将其移至舞台右侧的第20帧中。在创建补间时,Animate将计算影片剪辑在此中间的所有位置。结果将得到从左到右(即从第1帧移至第20帧)的元......
  • DLMS/COSEM中的信息安全:DLMS/COSEM安全概念(上)
        DLMS/COSEM中的信息安全描述并规定:    ——DLMS/COSEM安全概念;    ——选择加密算法;    ——安全密钥;    ——使用加密算法进行实体认证、xDLMSAPDU保护和COSEM数据保护。1.综述    DLMS/COSEM服务器的资源(COSEM对......
  • 文件IO学习——概念
    1、文件的概念文件的狭义定义:        指普通的文本文件,或二进制文件。包括日常所见的源代码、word文档、压缩包、图片、视频文件等等。文件的广义定义:        除了狭义上的文件外,几乎所有可操作的设备或接口都可视为文件。包括键盘、鼠标、硬盘、串口、触......
  • Mojo模块和包的概念详解
    Mojo提供了一个打包系统,可让您将代码库组织和编译库为可导入文件。本文介绍了关于如何将您的代码组织成模块和包的必要概念。并向您展示了如何使用命令行创建打包mojo的二进制包文件。Mojomodules了解Mojo软件包,首先需要了解Mojo模块。Mojo模块是一个Mojo源文件,其......