简体   繁体   English

从子类/子类/继承的类中获取基类/父类/父类

[英]Get base/parent/super class from a sub/child/inherited class

I'm trying to send a list of objects over a socket. 我正在尝试通过套接字发送对象列表。

The objects in the list contain an unserializable object and so cannot be sent, however it's base class is fully serializable and contains all the fields I need. 列表中的对象包含不可序列化的对象,因此无法发送,但是它的基类是完全可序列化的,并且包含我需要的所有字段。

So what I'm trying to do is convert the list to a list of the base class. 所以我想做的就是将列表转换为基类的列表。 The only way I could think so do this is as follows: 我认为这样做的唯一方法如下:

// subClassList is an ArrayList<SubClass>
ArrayList<BaseClass> baseClassList = new ArrayList<BaseClass>();
for(SubClass subClass: subClassList) {
    // cast to the base class
    baseClassList.add((BaseClass)subClass);
}

This however doesn't work as I still get the same NotSerializableException exception. 但是,这不起作用,因为我仍然收到相同的NotSerializableException异常。 From debugging the code I can see that the new list is still a list of the sub class, even though it has been cast. 通过调试代码,我可以看到即使已强制转换,新列表仍然是子类的列表。

Is there a way to achieve what I'm trying to do? 有没有办法实现我想要做的事情?

Casting a reference doesn't change the type of the actual object: 强制转换引用不会更改实际对象的类型:

String foo = "hello";
Object bar = (Object) foo;
System.out.println(bar); // Hello
System.out.println(bar.getClass()); // java.lang.String

If you want to only have an instance of the base class, you could create a constructor in the base class which simply creates a new instance of the base class given an instance of it, without trying to perform any sort of deep copy: 如果你想只有基类的一个实例,你可以创造一个简单的创建给它的一个实例的基类的新实例, 但不尝试进行任何形式的深拷贝基类的构造函数:

public BaseClass(BaseClass other) {
    this.x = other.x;
    this.y = other.y;
    this.z = other.z;
    // etc
}

Then in the code you've shown: 然后在代码中显示:

baseClass.add(new BaseClass(subClass));

Your approach doesn't work because even though you can use a super class variable to refer to the subclass object, the object itself is of the sub class type. 您的方法行不通,因为即使您可以使用超类变量来引用子类对象,该对象本身也是子类类型。

The best way is to either serialize the subclass, or extract the data from subclass and write them to a newly created super class. 最好的方法是序列化子类,或从子类中提取数据并将其写入新创建的超类。 Just have a static utility method to do the conversion build into the sub class.... 只需使用静态实用程序方法即可将转换构建到子类中。

Casting doesn't change the type of an object. 投射不会改变对象的类型。 It allows getting a reference of another type for the object iff the object has this other type. 如果对象具有其他类型的引用,则可以获取该对象的另一种类型的引用。 Upcasting is never necessary. 永远不需要上映。 You can use 您可以使用

String s = "hello";
Object o = s; // no cast needed

Downcasting is necessary, and will only work if the object has the type you cast it to: 向下转换是必要的,并且仅在对象具有将其强制转换为的类型时才起作用:

Object o = "hello";
Object o2 = Integer.valueOf(5);
String s = (String) o; // OK because o is a String
String s2 = (String) o2; // ClassCastException, because o2 is not a String.

So, your code is equivalent to 因此,您的代码等效于

ArrayList<BaseClass> baseClassList = new ArrayList<BaseClass>();
for(SubClass subClass: subClassList) {
    // cast to the base class
    baseClassList.add(subClass);
}

You must create a new object of the new type, using a copy constructor: 您必须使用复制构造函数创建新类型的新对象:

ArrayList<BaseClass> baseClassList = new ArrayList<BaseClass>();
for(SubClass subClass: subClassList) {
    // cast to the base class
    baseClassList.add(new BaseClass(subClass));
}

Your question embodies a contradiction in terms. 您的问题体现出术语上的矛盾。 If the base class is Serializable so are all its derived classes. 如果基类是可序列化的,则其所有派生类也是如此。 If your derived class contains references to non-serializable objects, just make them transient. 如果您的派生类包含对不可序列化对象的引用,则只需使其成为瞬态即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM