有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

客户端的java Android GAE多态性

我正在开发一个Android应用程序,它使用谷歌应用程序引擎(GAE)作为其后端,而且用很少的话来说,情况是

在后端(App Engine Java Endpoints模块),我有几个@Entity类,比如“Vehicle”、“Car”和“SportCar”,其中“SportCar”是“Car”的@Subclass,“Car”是“Vehicle”的@Subclass

@Entity
public class Vehicle{
    @Id
    private Long id;
    private String brand;
}

@Subclass(index = true)
public class Car extends Vehicle{

    private int wheelsNumber;
}

@Subclass(index = true)
public class SportCar extends Car{

    private boolean hasTurbo;
}

以及一个端点类“VehicleEndpoint”,它包含一个返回车辆实体列表的方法

@Api{name = "vehicleEndpoint", version = "v1", resource = "vehicle", ...}
public class VehicleEndpoint {

@ApiMethod(name = "listVehicles", path = "vehicle", 
           httpMethod = ApiMethod.HttpMethod.GET)
public CollectionResponse<Vehicle> listVehicles(){
     ...
 }
}

因此,当我从客户端(Android应用程序)调用“listVehicle”时,我收到了一个车辆对象列表,但不知道哪个是“Car”,哪个是“SportCar”。 我无法将这些车辆对象强制转换为Car或SportCar,因为客户端无法识别子类,因为它们不包括在“VehicleEndpoint”类中

List<Vehicle> listVehicle = vehicleEndpoint.listVehicles().execute().getItems();

我注意到的另一件事是,在安卓端,我们导入了Vehicle类,但它来自另一个包,而不是后端端的同一个包(后端包->;“com.my.example.backend.entity”和客户端导入->;“com.my.example.backend.endpoint.vehicleEndpoint.model.Vehicle”)

我们如何在客户端使用多态性?(始终希望返回最抽象的形式或绝对父级(在本例中为Vehicle),然后在客户端检查它是什么类型并使用它)

提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    And another thing which I noticed is that on the android side we import the Vehicle class but it is from another package, not the same package which is in the back-end side (Back-end package -> "com.my.example.backend.entity" and Client-side import-> "com.my.example.backend.endpoint.vehicleEndpoint.model.Vehicle").

    这是云端点中的正确行为。“com.my.example.backend.entity”是后端项目的包。当你升级同步项目时,Android Studio会为你创建一个客户端库,它会方便地将其添加到你的应用程序项目中。实际上,你可以去获取云端点。Android Studio生成的jar,并将其复制/粘贴到另一个Android项目中,然后使用您的API。包名“com.my.example.backend.endpoint.vehicleEndpoint.model.Vehicle”就是云端点创建jar文件的方式——正如您所猜测的,它来自端点类中的API注释。“车辆端点”例如:

    @Api(
            name = "vehicleEndpoint",
            version = "v1",
            scopes = {
                    Constants.EMAIL_SCOPE},
            clientIds = {
                    Constants.WEB_CLIENT_ID,
                    Constants.ANDROID_CLIENT_ID,
                    Constants.IOS_CLIENT_ID,
                    Constants.API_EXPLORER_CLIENT_ID},
            audiences = {
                    Constants.ANDROID_AUDIENCE},
            namespace = @ApiNamespace(
                    ownerDomain = Constants.API_OWNER,
                    ownerName = Constants.API_OWNER,
                    packagePath = Constants.API_PACKAGE_PATH
            )
    )
    

    这就是它的工作原理,是的,包名会有所不同,因为后者是一个生成的jar文件,我想这就是它通过API注释创建它的方式

    至于你的铸造问题,请记住,当你在客户机中使用API方法时,例如:

    List<Vehicle> listVehicle = vehicleEndpoint.listVehicles().execute().getItems();
    

    您将得到一个Json响应,然后该响应被欺骗回您的模型对象中。之所以知道这一点,是因为可以使用API资源管理器执行方法,并以纯文本形式查看响应。你看到的一切都是你得到的一切。像铸造这样的事情可能在那里不起作用。您可能需要在车辆对象中添加一个额外字段,以指示其类型

    希望这能让你对这个系统的工作原理有所了解