证明:白马非马

公孙龙说:“白马非马”。

当然,这可以理解成,“白马“和“马“不是全同的概念,白马是一种马。

但是,我要证明,白马连“一种马”都不是!

=========== 我是严肃的分割线 ============

首先,要明确,什么是“白马”。我们可以定义:

[quote]定义:如果一匹马身上的毛都是白的,那么这匹马可以称为“白马“。[/quote]

姑且认为是全白的吧,也认为我们在生活中经常可以找到这样的马。类似的,我们可以定义“黑马”、“枣红马”等等。

对于任何一匹马,我们可以从这匹马上揪下一些毛。没问题吧。

对于任何一匹吗,我们可以给这匹马添加一些毛。假设我们可以这样做吧,加上一些毛仍然是那匹马。

随便拿一匹马(不管颜色),再拿一根黑毛,加在这匹马上,得到的仍然是马。

根据李氏替换原则,我们把这匹马换成一匹白马,我们也可以往上添加一些黑毛。

但是,我们不能给他添加黑毛,因为一旦添加了,得到的就不是白马了!

这不是有问题吗,凡是马都能往上边添加黑毛,白马是马,为什么给白马加上黑毛以后,就不是白马了呢?


——+——~~#¥+@%*¥(@ 我是华丽的分割线 @(¥*%@+¥#~~——+——


Java程序员可以这样编程序:


package baima;

import java.util.*;

class Fur {}

class BlackFur extends Fur {}
class WhiteFur extends Fur {}

interface Horse {
List<Fur> getFurs();
}

interface WhiteHorse extends Horse {
List<WhiteFur> getFurs();{ // ERROR: The return type is incompatible with Horse.getFurs()
}


可惜Java不允许你这样定义“白马“。Java认为,List<WhiteFur>不是List<Fur>的子类。

如果你了解Java的“协变类型”,你会想这样定义:

interface Horse {
List<? extends Fur> getFurs(); // OK
}

interface WhiteHorse extends Horse {
List<? extends WhiteFur> getFurs(); // OK
}


编译正确。

然后我们试试:

class ConcreteWhiteHorse implements WhiteHorse {
private List<WhiteFur> furs = new ArrayList<WhiteFur>();

@Override
public List<WhiteFur> getFurs() {
return furs;
}
}

public class BaimaTest {
public static void main(String[] args) {
WhiteHorse myHorse = new ConcreteWhiteHorse();
List<WhiteFur> furs = myHorse.getFurs(); // ERROR: Type mismatch: cannot convert from List<capture#1-of ? extends WhiteFur> to List<WhiteFur>
furs.add(new WhiteFur());
}
}


编译通不过。Java不允许从List<? extends WhiteFur>到List<WhiteFur>的转换。

如果我们这样:


public class BaimaTest {
public static void main(String[] args) {
WhiteHorse myHorse = new ConcreteWhiteHorse();
List<? extends WhiteFur> furs = myHorse.getFurs();
furs.add(new WhiteFur()); // ERROR: The method add(capture#2-of ? extends WhiteFur) in the type List<capture#2-of ? extends WhiteFur> is not applicable for the arguments (WhiteFur)
}
}


furs是List<? extends WhiteFur>型的,不能添加WhiteFur类型的元素。

看样子,不进行强制类型转换,总是会出错的。

我们这样呢?


public class BaimaTest {
public static void main(String[] args) {
WhiteHorse myHorse = new ConcreteWhiteHorse();
List<WhiteFur> furs = (List<WhiteFur>) myHorse.getFurs(); // WARNING: Unchecked
furs.add(new WhiteFur());

Horse myHorseAgain = myHorse;
List<Fur> fursAgain = (List<Fur>) myHorseAgain.getFurs(); // WARNING: Unchecked
fursAgain.add(new BlackFur());

for (WhiteFur wf : myHorse.getFurs()) { // java.lang.ClassCastException
System.out.println("This is a '"+wf.getClass().getSimpleName()+"'");
}
}
}


看样子没问题吧,编译也通过了。我们成功地给一只白马增加了一根黑毛。你在想,为什么不能呢?白马也是马,马可以加黑毛,白马为什么不能加黑毛呢?

for循环中,试图把myHorse.getFurs()中的成员赋给wf。这一行连警告都没有,因为编译器认为myHorse.getFurs()本来就是List<WhiteFur>型的,当然可以赋值给WhiteFur型的wf呀。

但是,运行时出错。第一根毛是白毛,没错。但是,第二根是黑毛,赋给wf时,类型转换失败。

[quote]
This is a 'WhiteFur'
Exception in thread "main" java.lang.ClassCastException: baima.BlackFur cannot be cast to baima.WhiteFur
at baima.BaimaTest.main(BaimaTest.java:41)
[/quote]

.......................我是无奈的分割线......................

好了,你说,白马到底是不是马呢?

参考:http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值