我知道转发是不可行的。但我正在尝试解决它。
这就是我所拥有的。
public class Ticket{
public int number;
public String description;
}
public class MyTicket extends Ticket{
public String status;
}
但在我的应用程序中,我想使用MyTicket类,因为我不想强制更改原始Ticket对象。因此,当Ticket对象从调用(webservice,DB等)返回时,我尝试向下转换为MyTicket,它显然会失败。
MyTicket mt=(MyTicket)ws.getTicket(1234);
所以我试图想办法解决这个问题。我正在考虑编写一个“copyAttributes”方法或复制MyTicket类的构造函数中的属性,如下所示:
MyTicket mt=new MyTicket(ws.getTicket(1234));
public class MyTicket extends Ticket {
public String status;
public MyTicket(Ticket tckt){
//copy tckt attributes to MyTicket attributes
}
}
有没有办法获取类的属性并将它们设置为另一个类? 或者有一种截然不同的方式,我错过了它?
* 解决方案: *所以我采取了以下解决方案并提出了这个问题。如果在传输发生之前未找到主票证,我需要将更改返回null:
public class MyTicket extends Ticket {
public String status;
public MyTicket(){}
public static MyTicket newInstance(Ticket tckt){
MyTicket mytkt=null;
if(tckt!=null){//copy tckt attributes to MyTicket attributes
BeanUtilsBean.getInstance().getConvertUtils().register(false,true,-1);
mytkt = new MyTicket();
BeanUtils.copyProperties(mytkt, tckt);
}
return mytkt;
}
}
答案 0 :(得分:1)
我认为你做得对。如果您的对象增长,您可能希望使用Apache BeanUtils
来帮助您进行复制。
答案 1 :(得分:1)
Downcasting。看来Web服务返回的Ticket对象实际上并不是MyTicket,因此向下转换会在运行时抛出ClassCastException
。
在构建MyTicket时,我将使用Web服务返回的Ticket,我将在Ticket类中定义一个复制构造函数,该构造函数将获取票证对象并复制属性。这个拷贝构造函数将在MyTicket的构造函数中调用,该构造函数接受Ticket对象。
public class Ticket{
public int number;
public String description;
public Ticket(Ticket ticket)
{
this.number = ticket.number;
this.description = ticket.description;
}
}
public class MyTicket extends Ticket{
public String status;
public MyTicket(Ticket ticket)
{
super(ticket);
}
public MyTicket(Ticket ticket, String status)
{
super(ticket);
this.status = status;
}
}
答案 2 :(得分:1)
为什么不在这种情况下使用聚合+ getter / setter?
public class MyTicket {
private Ticket ticket;
private String status;
public MyTicket(Ticket ticket) {
this.ticket = ticket;
}
public int getNumber() { return ticket.number; }
public void setNumber(int number) { ticket.number = number; }
public String getDescription { return ticket.description; }
public void setDescription { ticket.description = description; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
}
然后,您可以按照建议创建对象:
MyTicket mt = new MyTicket(ws.getTicket(1234));
答案 3 :(得分:0)
我建议你实现像 Cloneable 这样的东西(但不是标准的Java,在这里可以提供超类中的抽象方法)接口。 MyTicket 类中的类似内容:
@Override
public Ticket clone() {
// copying stuff by calling a "copy constructor"
return new MyTicket(this);
}
private MyTicket(MyTicket t) {
}
答案 4 :(得分:0)
继承:
public class ThisIsASubClass extends ThisIsASuperClass{
{
//declare stuff here
Object o = "Let's presume a string is passed";
super(o); //runs the super class (ThisIsASuperClass in this case), sending an object if needed (effectivly running the super class inside of the subclass)
//put the subclass code here
}
我发现的一个很好的例子(很长,但我读长篇大论没有问题。如果你是程序员,你也不应该。):
以下是类和对象课程中提供的Bicycle类可能实现的示例代码:
public class Bicycle {
// the Bicycle class has
// three fields
public int cadence;
public int gear;
public int speed;
// the Bicycle class has
// one constructor
public Bicycle(int startCadence, int startSpeed, int startGear) {
gear = startGear;
cadence = startCadence;
speed = startSpeed;
}
// the Bicycle class has
// four methods
public void setCadence(int newValue) {
cadence = newValue;
}
public void setGear(int newValue) {
gear = newValue;
}
public void applyBrake(int decrement) {
speed -= decrement;
}
public void speedUp(int increment) {
speed += increment;
}
}
作为Bicycle的子类的MountainBike类的类声明可能如下所示:
public class MountainBike extends Bicycle {
// the MountainBike subclass adds
// one field
public int seatHeight;
// the MountainBike subclass has one
// constructor
public MountainBike(int startHeight,
int startCadence,
int startSpeed,
int startGear) {
super(startCadence, startSpeed, startGear);
seatHeight = startHeight;
}
// the MountainBike subclass adds
// one method
public void setHeight(int newValue) {
seatHeight = newValue;
}
}
MountainBike继承了Bicycle的所有字段和方法,并添加了字段seatHeight和设置它的方法。除了构造函数之外,就好像你已经从头开始编写了一个新的MountainBike类,有四个字段和五个方法。但是,您不必完成所有工作。如果Bicycle类中的方法很复杂并且需要花费大量时间来调试,那么这将特别有价值。 您可以在子类中执行的操作
子类继承其父级的所有公共成员和受保护成员,无论子类在哪个包中。如果子类与其父类在同一个包中,它还继承父类的包私有成员。您可以按原样使用继承的成员,替换它们,隐藏它们,或用新成员补充它们:
继承的字段可以直接使用,就像任何其他字段一样。 您可以在子类中声明一个与超类中的字段同名的字段,从而隐藏它(不推荐)。 您可以在子类中声明不在超类中的新字段。 继承的方法可以直接使用。 您可以在子类中编写一个新实例方法,该方法与超类中的签名具有相同的签名,从而覆盖它。 您可以在子类中编写一个新的静态方法,该方法与超类中的签名具有相同的签名,从而隐藏它。 您可以在子类中声明不在超类中的新方法。 您可以编写一个子类构造函数,以隐式方式或使用关键字super来调用超类的构造函数。
本课程的以下部分将对这些主题进行扩展。 超类中的私人会员
子类不继承其父类的私有成员。但是,如果超类具有访问其私有字段的公共或受保护方法,则子类也可以使用这些方法。
嵌套类可以访问其封闭类的所有私有成员 - 包括字段和方法。因此,子类继承的公共或受保护嵌套类可以间接访问超类的所有私有成员。 投射物品
我们已经看到一个对象是实例化它的类的数据类型。例如,如果我们写
public MountainBike myBike = new MountainBike();
然后myBike属于MountainBike类型。
MountainBike是Bicycle和Object的后裔。因此,MountainBike是一个自行车,也是一个对象,它可以在任何需要自行车或物体对象的地方使用。
反过来不一定如此:自行车可能是MountainBike,但不一定如此。类似地,对象可以是自行车或山地自行车,但不一定。
Casting显示在继承和实现允许的对象中使用一种类型的对象代替另一种类型。例如,如果我们写
Object obj = new MountainBike();
然后obj既是一个物体也是一个山地自行车(直到obj被指定为另一个不是Mountainbike的物体)。这称为隐式转换。
另一方面,如果我们写
MountainBike myBike = obj;
我们会得到编译时错误,因为编译器不知道obj是MountainBike。但是,我们可以告诉编译器我们承诺通过显式转换将MountainBike分配给obj:
MountainBike myBike = (MountainBike)obj;
此强制转换插入运行时检查,为obj分配MountainBike,以便编译器可以安全地假设obj是MountainBike。如果obj在运行时不是Mountainbike,则会抛出异常。 注意:您可以使用instanceof运算符对特定对象的类型进行逻辑测试。由于播放不当,这可以避免运行时错误。例如:
if (obj instanceof MountainBike) {
MountainBike myBike = (MountainBike)obj;
}
这里,instanceof运算符验证obj是否引用了MountainBike,以便我们可以使用知道不会抛出运行时异常来进行转换。
TL; DR:如果使用继承,任何正方形都是矩形,但并非所有矩形都是正方形..
http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
答案 5 :(得分:0)
如果你要回来的对象被创建为Ticket对象而不是MyTicket,那么我会按照你提出的复制构造函数的方式来接近它。
答案 6 :(得分:0)
最好的方式,使用最少冗余的代码,将是MyTicket
包含原始Ticket
实例(聚合)和在需要的地方使用其属性,而无需事先复制任何内容。
public class MyTicket extends Ticket {
private final Ticket t;
public MyTicket(Ticket t) {
this.t = t;
}
}
如果你需要通过getter公开所有属性,那么这将没有多大用处。只有在内部需要Ticket
属性进行某些计算时才会有所帮助。