Java中什么是多态?多态的优势和劣势是什么?

简介: Java中什么是多态?多态的优势和劣势是什么?

什么是多态?

在编程语言和类型论中,多态(英语:polymorphism)指为不同数据类型的实体提供统一的接口。 多态类型(英语:polymorphic type)可以将自身所支持的操作套用到其它类型的值上。


面向对象的三大特征:封装性、继承性、多态性,多态性就是多态,多态是在封装的升华,可以说没有封装就么有多态。


extends继承或者implements实现,无论是类与类之间的继承、类与接口之间的实现还是接口与接口间的继承,反正总会出现上下的层次关系,这种关系的产生就是多态性出现的前提。


为了更好的明白什么是多态,来个小demo吧!

多态demo

场景:有学生、老师、超级管理员,难道每一个都要重复写吗,这个岂不是很繁琐,维护起来很困难,若干年后当做diamagnetic重构的时候可能你都不想看你的代码了吧,应该是真的很繁琐,很复杂。


下面我们将创建三个子类【Student、Teacher、Administrator】和一个父类【Person】以及一个测试函数。


父类,包含普通的变量和一个show方法。


Person.java

package DT.demo1;
public class Person {
    private String name;
    private int age;
    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void show(){
        System.out.println(name+","+age+"展示");
    }
}

学生类,继承父类属性和方法并重写父类show方法


Student.java

package DT.demo1;
public class Student extends Person{
    @Override
    public void show() {
        System.out.println("学生的信息"+getName()+","+getAge());
    }
}


老师类,继承父类属性和方法并重写父类show方法


Teacher.java

package DT.demo1;
public class Teacher extends Person{
    @Override
    public void show() {
        System.out.println("老师的信息"+getName()+","+getAge());
    }
}

超级管理员类,继承父类属性和方法并重写父类show方法

Administrtors.java

package DT.demo1;
public class Administrtors extends Person{
    @Override
    public void show() {
        System.out.println("管理员的信息"+getName()+","+getAge());
    }
}

为了不需要重写我们只需要new出想要的对象然后传入即可。这样就算后面需要添加更多类型的用户也只需要new出对象,控制传入register的参数即可。注意因为main函数是static的,所以下面的register也必须是static类型的。


Test.java

package DT.demo1;
public class Test{
    public static void main(String[] args) {
        Student student=new Student();
        student.setName("张三");
        student.setAge(20);
        Teacher teacher=new Teacher();
        teacher.setName("李四");
        teacher.setAge(22);
        Administrtors admin=new Administrtors();
        admin.setName("不良使");
        admin.setAge(18);
        register(student);
        register(teacher);
        register(admin);
    }
     public static void register(Person p){
        p.show();
     }
}

image.pngJava多态优势是什么

为了考虑到篇幅和耗时,我们将所有的类写到一个类里面。注意,平时尽量不要这么操作,这里只是为了单纯的图快。

Test.java

package DT.demo2;
// todo  为了方便查看就不把每一个类分开写了      下面都写到这一个Test.java  文件中
public class Test {
    public static void main(String[] args) {
        // todo  多态方式创建对象     格式  :   Fu fu = new Zi();
        Animal animal=new Cat();
        //  todo  多态方式调用成员变量,编译看左边,运行也看左边
        //  *   编译看左边  ,  javac编译的时候会看等号左边父类中有没有这个变量, 如果有编译成功,如果没有,编译失败
        //  *   运行看左边  ,  javac编译的时候实际获取的是左边父类中成员变量的值
        System.out.println(animal.name);  // todo  动物
        //   调用成员方法     编译看左边,运行看右边
        //  *   编译看左边  ,  javac编译的时候会看等号左边父类中有没有这个变量, 如果有编译成功,如果没有,编译失败
        //  *   运行看左边  ,  javac编译的时候实际上运行的是子类中的方法
        animal.show();   // todo   Cat的show()方法
        // 理解
        Animal animal1=new Dog();
        //现在用animal1是Animal类型,都会默认从Animal这个类中去找
    }
}
class Animal{
    String name="动物";
    public void show(){
        System.out.println("Animal的show()方法");
    }
}
class Cat extends Animal{
    String name="猫";
    @Override
    public void show() {
        System.out.println("Cat的show()方法");
    }
}
class Dog extends Animal{
    String name="狗";
    @Override
    public void show() {
        System.out.println("Dog的show()方法");
    }
}

1、

在多态的形式下,右边的对象可以实现解耦合,便于扩展和维护


例如:

Person person = new Student();
person.work();  //  多态new出来的对象调用woek方法

但是当业务发生了变化时,我需要一个新对象【可以是老师、助教等,但是必须是Person的子类】 只需要修改 new Student();即可


2、

定义方法的时候,使用父类型作为参数,可以接收所有子类对象,体现了多态的扩展性于遍历


任何事物都不是完美无缺的,说完多态的优势,下面我们就来看看多态的劣势吧。


Java多态劣势是什么

不能使用子类的特定功能。


嗯~,其实多态的劣势来源于多态的优势。为什么不修改呢,因为两者是并生的,而多态的优势 > 多态的劣势。任何专业术语,语言特性以及框架的出现都是为了方便性,所以~,你们明白的。


下面来看看多态的劣势吧!image.png



我们可以发现animal对象没有找到lookHome()这个方法,是不是很好奇,我明明new的是子类的Dog的对象,为什么Dog类中的方法却不能调用了呢?


解析:


多态new出来的对象,在调用成员方法和变量的调用和一般常规new出来的对象有些许不同。


变量调用: 编译看左边,运行看左边


编译看左边 , javac编译的时候会看等号左边父类中有没有这个变量, 如果有编译成功,如果没有,编译失败

运行看左边 , javac编译的时候实际获取的是左边父类中成员变量的值


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


编译看左边 , javac编译的时候会看等号左边父类中有没有这个变量, 如果有编译成功,如果没有,编译失败

运行看左边 , javac编译的时候实际上运行的是子类中的方法


产生原因: 多态new出来的对象方法调用 编译看左边,运行看右边 。而父类没有这个方法,所以new出来的对象自然找不到。承受的范围大了。


解决方案: 向下转型就行了,但是需要注意的是向下转型是不可以随便转的,佛则会报错。


Test.java


package DT.demo3;
public class Test {
    public static void main(String[] args) {
        //   堕胎方式创建对象
        Animal animal=new Dog();
        Dog dog=(Dog)animal;
        dog.lookHome();
    }
}
class Animal{
    public void eat(){
        System.out.println("动物在吃饭");
    }
}
class Dog extends Animal{
    // 继承重写父类Animal的eat方法
    @Override
    public void eat() {
        System.out.println("够吃骨头");
    }
    // 狗自带方法,父类没有
    public void lookHome(){
        System.out.println("狗看家");
    }
}
class Cat extends Animal{
    // 继承重写父类Animal的eat方法
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    // 猫自带方法,父类没有
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}

image.pngimage.png




目录
相关文章
|
11天前
|
Java
Java面向对象编程新篇章:多态,你准备好了吗?
【6月更文挑战第17天】Java的多态性是面向对象编程的核心,它允许通过统一的接口处理不同类型的对象。例如,在一个虚拟宠物游戏中,抽象类`Pet`定义了`speak()`方法,猫、狗和鹦鹉等子类各自重写此方法以实现独特叫声。在`main`方法中,使用`Pet`类型的引用创建子类对象并调用`speak()`,多态机制确保调用实际对象的方法,实现代码的灵活性和可扩展性。通过多态,我们能以更低的耦合度和更高的复用性编写更优雅的代码。
|
2天前
|
Java 机器人 程序员
深入理解Java中的类与对象:封装、继承与多态
深入理解Java中的类与对象:封装、继承与多态
|
3天前
|
安全 Java
深度解读Java的继承和多态的特性
深度解读Java的继承和多态的特性
|
6天前
|
Java 编译器
Java多态(如果想知道Java中有关多多态的知识点,那么只看这一篇就足够了!)
Java多态(如果想知道Java中有关多多态的知识点,那么只看这一篇就足够了!)
|
9天前
|
Java 数据安全/隐私保护
Java基础之类封装、继承、多态
Java基础之类封装、继承、多态
11 4
|
9天前
|
Java 数据安全/隐私保护
Java基础之类封装、继承、多态
Java基础之类封装、继承、多态
10 2
|
9天前
|
Java 数据安全/隐私保护 开发者
Java是一种完全支持面向对象编程的语言,其面向对象特性包括封装、继承、多态和抽象等
【6月更文挑战第18天】**面向对象编程(OOP)通过对象封装状态和行为,实现问题域的抽象。Java全面支持OOP,核心特性包括**: - **封装**:保护数据安全,隐藏内部细节。 - **继承**:子类继承父类属性和行为,促进代码重用。 - **多态**:一个接口多种实现,增强灵活性和扩展性。 - **抽象**:通过接口和抽象类抽离共性,简化复杂性。 **Java的OOP便于理解和解决复杂系统问题。**
21 3
|
9天前
|
安全 Java 数据安全/隐私保护
Java基础之类封装、继承、多态
Java基础的封装、继承和多态是OOP的核心。封装通过访问控制(如private)隐藏类的内部细节,提供公共接口供外部交互。例如,`Person`类封装`name`和`age`,通过`getName()`和`setAge()`方法访问。继承允许子类(如`Dog`)继承父类(如`Animal`)的属性和方法,并可扩展或覆盖。多态使得父类引用可指向子类对象,调用方法时根据实际对象类型执行,如不同动物的`makeSound()`。接口实现多态提供了一种定义行为而不必关心实现的方式。向上转型(子类→父类)安全且默认,而向下转型(父类→子类)需类型检查以避免异常。
9 1
|
10天前
|
安全 Java 开发者
类与对象:Java中的封装、继承与多态
Java面向对象三大特性:封装(隐藏对象细节,增强安全与复用),继承(代码复用与扩展,如Dog继承Animal),多态(统一接口,不同实现,如Playable接口的Piano和Guitar)。通过示例展示了如何在实践中应用这些概念。【6月更文挑战第16天】
17 2
|
10天前
|
Java 开发者
深入Java多态:从“一个消息”到“多种响应”的进化之路
【6月更文挑战第17天】Java多态性简化教育软件开发:通过抽象Course类定义teach()方法,子类如MathCourse、EnglishCourse和ScienceCourse重写该方法,实现特定教学内容。在CourseManagementSystem中,多态允许通过Course引用调用不同课程的teach(),展示“一个消息,多种响应”的能力,增强代码灵活性和可维护性,是面向对象编程的关键。