早上好,
这是我最近提出的一个关于抽象类的正确用法的问题的补充。
我目前有一个抽象类和两个子类,如图所示:
public abstract class Vehicle {
String type;
String color;
...getter and setters
}
从父级继承getter和setter,再加上一个唯一属性
public class Truck extends Vehicle{
String pickupBed;
public setPickupBed(String pickupBed){
this.pickupBed = pickupBed;
}
public getPickupBed(String pickupBed){
return pickupBed;
}
.....Parent class getter and setters
}
从父级继承getter和setter
public class Car extends Vehicle{
.....Parent class getter and setters
}
例如,当我在dao类中创建一个方法时
public Vehicle selectAllRecords(){
...DO database stuff
return VehicleRowMapperWithData();
}
如果我打电话 Vehicle veh = selectAllRecords()
我不能这么做 veh.getPickupBed()
我明白这不是它的工作原理,但我如何才能做到这一点?我试过选角,但没用。
提前谢谢
1条答案
按热度按时间f5emj3cl1#
没有简单的答案。
使用数据库工具
一些数据库支持“子类化”;你可以把一张table延伸到另一张table上。例如,postgres可以做到这一点。许多db抽象层都不支持它,psql也不完全支持它(它可以工作并得到维护,但并不推荐)。只要db或多或少地完美地反映了java代码的工作方式,那么您使用的工具至少有可能会像变戏法一样弄清楚该怎么做。
编写代码
暂时忘记java。看看你的数据库表。你怎么知道某辆车实际上是辆卡车?有单独的table叫“卡车”吗?是否有“vehicletype”列,并且每种车辆的所有自定义字段都是db表中的一列,而不是该车辆的每一行都为该列保留null或某个伪值?在这种情况下,您需要编写一个大的if/elseif块来检查vehicle type列,然后调用right
new Car(...)
,或new Truck(...)
建造师。一般来说,java对象模型和db模型之间存在不匹配。
不过,这通常是件好事!jpa和friends在这两个完全匹配的情况下工作得最好,但是考虑到java是面向对象的,喜欢层次结构,而dbs确实不喜欢,这不一定是个好主意。但是,一旦java的类结构与db存储内容的方式不匹配(例如:在db中,它是一个带有“type”列的表,在java中,它是类的层次结构,没有“type”字段,而是有car的示例,truck的示例,这意味着自动化工具不能神奇地把一个变成另一个。你写的代码可以做到这一点。
将java与数据库匹配
不要试图确保db的表定义与java代码完全匹配,这很难(psql)或是不可能(大多数其他db系统都没有子表功能),就像他们说的那样,如果你不能如愿,也许会如愿:忘记java中的类型层次结构吧。只有一个类车辆和一个枚举车辆类型。这有点令人讨厌,因为它打破了各种惯用的java规则;现在,代表公路自行车的车辆示例有
getPickupBed()
奇怪的方法。这让我们回到事情的简单真相:
idiomatic(正如大多数教程所推荐的那样,如果你这样做的话,所有的工具都能工作得最好,它是大多数数据库中受支持的路径,工作流中的任何问题都会很早被发现并很快得到解决,因为大多数使用这个软件的人都和你一样工作,这就是idiomatic的意思)db设计很重要。
惯用代码很重要。
惯用db设计表示的相同概念通常与惯用代码设计不匹配。
我们喜欢自动转换。
这些东西彼此不完全兼容。