0

I have two distinct classes:

internal data class ClassB(
        @Json(name = "id") val id: String?,
        @Json(name = "name") val name: String?,
        @Json(name = "url") var contentUrl: String?,
        @Json(name = "mediaImageUri") val coverUrl: String?,
        @Json(name = "mediaVideoCoverImageUri") val videoCoverUrl: String?
        
)

internal data class ClassC(
        @Json(name = "tileId") val id: String?,
        @Json(name = "friendId") val friendId: String?,
        @Json(name = "profilePictureUri") var profilePicture: String?,
        @Json(name = "name") var name: String?
)

That inherit from the same class:

internal open class ClassA(
        @Json(name ="type") var type: String?,
        @Json(name ="sponsor-offer") var offer: SponsorOffer?,
        @Json(name ="date") var date: Date?,
        @Json(name ="weight") var priorityWeight: Int?
)

I am using an API call that returns a list of ClassA and is parsed by retrofit into a List, and need to cast each object onto one of the child classes before adding it to a local ArrayList<Any>

I am attempting to do this by iterating through the list returned and checking for the proprietary attributes of Classes B and C. then casting to object to the appropriate one before adding it to a local array. How can I check for these attributes? Is there a better way to do what I am attempting to do?

classA.javaClass.kotlin.members.any is not working

andrewedgar
  • 797
  • 1
  • 12
  • 46

1 Answers1

0

If ClassB and ClassC both extend ClassA, then you can just use the is keyword to check the type and then cast it

val thing: ClassA = getThing()
if (thing is ClassB) {
    // thing should have been smart-cast to ClassB in here, or you can:
    val thingB = thing as ClassB
}

or you could use a when block to check the possible types.

Or you can use the safe-cast operator as?, which evaluates to null if you can't cast to that type:

(thing as? ClassB)?.let { ... } ?: // it was null, so it's not ClassB, so...

But if you're doing this to put them into an ArrayList<Any> then there's no point casting them, that information is lost - it's a list of Anys! You'll have to recheck the type and cast each item when you take them out.

If you want to hold separate lists of ArrayList<ClassB> and ArrayList<ClassC>, then casting so you can put them in the right list (which will only accept that type) is ok - you'll know exactly what you're getting out of those

cactustictacs
  • 17,935
  • 2
  • 14
  • 25
  • Thank you for your response. I am parsing the response with Retrofit. How do I make retrofit aware of which item to parse into Class B and which to parse into Class C? Your first block is not working, I'm assuming because it is only recognizing it as Class A – andrewedgar Dec 01 '20 at 05:55
  • Well in your code as-is, there's no relationship between ``ClassB`` and ``ClassA``, same for ``ClassC``. There's no inheritance going on, neither of them have ``ClassA`` as a supertype - and they can't anyway! You can't have an ``open`` ``data class`` in Kotlin (not at the moment anyway). If you're talking about nested objects in the JSON, take a look at https://stackoverflow.com/questions/32942661/how-can-retrofit-2-0-parse-nested-json-object – cactustictacs Dec 02 '20 at 00:34
  • Another approach (I don't know what you're doing exactly and I've barely touched Retrofit) is to create a ``sealed class`` which ``ClassB`` and ``ClassC`` both derive from, and add that as a (nullable if optional) parameter in ``ClassA`` - that way each ``ClassA`` can "contain" a ``ClassB`` or ``ClassC``, and you can pull them out easily. I don't know the details of how you'd parse nested things like that, but it should be pretty common right! – cactustictacs Dec 02 '20 at 00:37
  • I ended up giving class A all of the attributes of class B and C. Bad solution but I was in a bind. Thank you for your time, thought! – andrewedgar Dec 02 '20 at 00:39
  • check my comment after that one, it's sort of the same thing but seems more like how it should be organised, if that's the structure of your data. Hope it works out! – cactustictacs Dec 02 '20 at 00:40