1.2.2 子类型的问题

来源:互联网 发布:httpclient put json 编辑:程序博客网 时间:2024/04/29 01:58

Java中,我们用父类和子类来实现这种继承关系。为了更好的表达为什么会产生不匹配的问题,我们来继续之前的例子。我们要实现既能接受用户银行账户,同时也能使用信用卡和借记卡。因此,对于同一账户来说,可以有多种支付方法。为了实现这种功能最明显的做法就是在BillingDetails类使用继承的方式。

我们把BillingDetails类作为一个抽象类,同时可以有几个继承它的子类,如CreditCardDriectDebitCheque等等。在不同的子类中,细节可能差别不大,但是具体的功能方面可能存在很大的差别。图1.3中的UML类图描述了这个对象模型。


SQL并没有提供这种直接的继承。我们不能把定义一个表CREATE_CARD_DETAILS并把它作为BILLING_DETAILS的子类,也就是类似于这样的写法CREATE TABLECREDIT_CARD_DETAILS EXTENDS BILLING DETAILS(…)

在第3章的3.6类继承关系的映射当中,我们讨论了关于存在继承关系的类如何与数据库表做映射的问题。当然这个问题在开发社区中并没有被很好的理解,而解决方案也是千篇一律。它们都没有能够解决继承映射的问题,而且在我们引入继承之后,多态也随之出现了。

User类和BillingDetails存在着联系,这被称之为多态连接。在实际运行中,一个User对象可能和任何一个BillingDetails的子类存在这种关联。同样的,我们书写这样的查询的时候,通常面向的BillingDetails,但是返回的是BillingDetails子类的对象。这被称之为多态查询。

由于SQL数据库并不存在继承的概念,因此实现多态也是一件很困难的事情。而外键约束通常也只能针对一个表,你不能在同一个外键指向多个表。我们也可以这样理解,Java中对于类型的约束没有SQL中那么严格。幸运的是,在第三章中,我们针对多态连接和多态查询都给出了行之有效的解决方案。

所以造成这种子类型的不匹配的原因就是Java的继承模型无法在SQL数据库中表现出来的缘故。下一个方面的问题就是对象ID的问题。你可能注意到我们把UserName作为User表的主键,这是一个明智的选择吗?并不一定,就像你接下来即将要看到的。