面向对象方法理论学习:为什么Java、C++范型不能继承

先看一个Java范型的例子,设B是A的子类: 

class A {...}
class B extends A {...}

则我们可以这样使用范型:

import java.util.*;
...
LinkedList<A> a = new LinkedList<A>();
a.add(0, new A());
a.add(1, new B());

这里范型List<A>定义了一个元素为A的List,所以往这个List添加元素的时候可以添加A类或者A的子孙类对象,所以上述两个add()调用很正常。

我们的问题是:子类范型与父类范型相容吗?

比如在上例中,List<A>和List<B>分别被称为父类范型和子类范型,则后者与前者相容吗?

之所以这个问题很重要,是因为子类与父类是相容的。就像上面例子中,凡是父类A的对象可以出现的地方,都可以用子类B的对象替换。这正是面向对象继承机制的精髓。比如,下面语句是正确的:

A  a = new B();

但是,子类范型和父类范型之间却没有这种相容性。比如下面的语句是错误的:

LinkedList<A> a = new LinkedList<B>();

为什么呢?很多高手会告诉你因为范型不是类,所以虽然类之间有继承性但是范型之间没有继承性。这话没错,但是说了等于白说,还是没有解释清楚为什么范型之间没有继承性。

假设上述语句是合理的,再假设A的子类有两个,分别是B和C,且B和C之间没有相容性,即相互不是对方的祖先。则下述语句显然是错误的:

LinkedList<B> b = new LInkedList<B>();
b.add(0, new C());

另一方面,

LinkedList<B> b = new LinkedList<B>();
LinkedList<A> a = b;
a.add(0, new C());

看出问题了吗?链表b中居然可以加入C类的对象!这就是问题的所在。所以,如果允许范型继承,则范型可以轻松地突破范型的限制,使得一个不相容类型的对象也能参与计算。这就是不论C++还是Java,抑或是其他的或者未来的面向对象语言,都不可能允许范型继承的原因。

再次强调:类继承和范型继承是两回事。比如下面语句是合理的:

List<A> a = new LinkedList<A>();

有读者问:那Python呢?

Python并没有范型机制。范型是强类型语言才会有的机制。Python是弱类型语言,编译时并不检查数据的类型,所以没有范型机制。范型机制本质上是一种语法机制,是为了防止程序员在语法上犯错,比如向一个LinkedList<B>类型的链表中加入C类型的对象。在Java的字节码(bytecode)中,并没有范型的概念。

现在,你对范型的本质是不是有了更深刻的认识?

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方林博士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值