首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Java编程教程】详解Java 协变返回类型

【Java编程教程】详解Java 协变返回类型

作者头像
IT咸鱼
发布2025-05-20 18:30:48
发布2025-05-20 18:30:48
9800
代码可运行
举报
运行总次数:0
代码可运行

协变返回类型指定返回类型可以在与子类相同的方向上变化。

在 Java5 之前,不可能通过改变返回类型来覆盖任何方法。但是现在,从 Java5 开始,如果子类重写任何返回类型为 Non-Primitive 的方法,但它会将其返回类型更改为子类类型,则可以通过更改返回类型来重写方法。让我们举一个简单的例子:

注意:如果您是 Java 初学者,请跳在了解 OOP 概念后再返回阅读本篇教程。

# 协变返回类型的简单示例

文件名:B1.java

代码语言:javascript
代码运行次数:0
运行
复制
class A{    
A get(){return this;}    
}    

class B1 extends A{    
@Override  
B1 get(){return this;}    
void message(){System.out.println("欢迎使用协变返回类型");}    

public static void main(String args[]){    
new B1().get().message();    
}    
}

输出:

代码语言:javascript
代码运行次数:0
运行
复制
欢迎使用协变返回类型

上面的例子可以看到,A类的get()方法的返回类型是A,B类的get()方法的返回类型是B。两种方法返回类型不同,但都是方法重写. 这称为协变返回类型。关注公众号鸭哥聊Java,获取651页Java面试题

# 协变返回类型的优点

以下是协变返回类型的优点。

  1. 协变返回类型有助于避免类层次结构中令人困惑的类型转换,使代码更易用、可读和可维护。
  2. 在方法覆盖中,协变返回类型提供了拥有更多指向返回类型的自由。
  3. 协变返回类型有助于防止返回时的运行时ClassCastExceptions。

让我们举个例子来理解协变返回类型的优点。

文件名:CovariantExample.java

代码语言:javascript
代码运行次数:0
运行
复制
class A1  
{  
    A1 foo()  
{  
        return this;  
    }  

    void print()  
{  
        System.out.println("Inside the class A1");  
    }  
}  


// A2 是 A1 的子类  
class A2 extends A1  
{  
    @Override  
    A1 foo()  
{  
        return this;  
    }  

    void print()  
{  
        System.out.println("Inside the class A2");  
    }  
}  

// A3 是 A2 的子类  
class A3 extends A2  
{  
    @Override  
    A1 foo()  
{  
        return this;  
    }  

    @Override  
    void print()  
{  
        System.out.println("Inside the class A3");  
    }  
}  

public class CovariantExample  
{  
    // main方法  
    public static void main(String argvs[])  
{  
       A1 a1 = new A1();  

       //这样写是没问题的  
       a1.foo().print();  

       A2 a2 = new A2();  

       // 我们需要进行类型转换才能实现  
             // 读者更清楚创建的对象类型    
       ((A2)a2.foo()).print();  

       A3 a3 = new A3();  

       // 进行类型转换  
       ((A3)a3.foo()).print();  
    }  
}

输出:

代码语言:javascript
代码运行次数:0
运行
复制
Inside the class A1
Inside the class A2
Inside the class A3

解释:在上面的程序中,A3类继承了A2类,A2类继承了A1类。因此,A1 是类 A2 和 A3 的父类。因此,类 A2 和 A3 的任何对象也是类型 A1。由于方法foo()的返回类型在每个类中都是相同的,我们不知道该方法实际返回的对象的确切类型。我们只能推断返回的对象将是 A1 类型,这是最通用的类。

我们不能确定返回的对象是 A2 还是 A3。这是我们需要进行类型转换以找出从方法foo()返回的对象的特定类型的地方. 它不仅使代码冗长;它还需要程序员的精确度,以确保正确完成类型转换;否则,很有可能获得ClassCastException。

更糟的是,想想层次结构下降到 10 - 15 个类甚至更多的情况,并且在每个类中,方法foo()具有相同的返回类型。这足以让代码的读者和编写者陷入噩梦。关注公众号Java面试那些事儿,获取651页Java面试题

写上面的更好的方法是:

文件名:CovariantExample.java

代码语言:javascript
代码运行次数:0
运行
复制
class A1  
{  
    A1 foo()  
{  
        return this;  
    }  

    void print()  
{  
        System.out.println("Inside the class A1");  
    }  
}  

// A2 是 A1 的子类  
class A2 extends A1  
{  
    @Override  
    A2 foo()  
{  
        return this;  
    }  

    void print()  
{  
        System.out.println("Inside the class A2");  
    }  
}  

// A3 是 A2 的子类  
class A3 extends A2  
{  
    @Override  
    A3 foo()  
{  
        return this;  
    }  

    @Override  
    void print()  
{  
        System.out.println("Inside the class A3");  
    }  
}  

public class CovariantExample  
{  
    // main方法  
    public static void main(String argvs[])  
{  
       A1 a1 = new A1();  
       a1.foo().print();    
       A2 a2 = new A2();     
       a2.foo().print();  
       A3 a3 = new A3();  
       a3.foo().print();   
    }  
}

输出:

代码语言:javascript
代码运行次数:0
运行
复制
Inside the class A1
Inside the class A2
Inside the class A3
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-03-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT咸鱼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # 协变返回类型的简单示例
  • # 协变返回类型的优点
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档