Home > Net >  Class cast exception between parent and child classes
Class cast exception between parent and child classes

Time:07-01

I waas develop an app in kotlin, when I get to the following error:

enter image description here

rise by the following check in the first line:

(it.responseBase as ValidateOtpResponse).let {resp ->  // error rise here
                            if (resp.code == "200") {
                                val sucessDialog = GenericDialog(
                                    context = requireContext(),
                                    icon = R.drawable.ic_tick_green,
                                    title = getString(R.string.change_password_title),
                                    subtitle = getString(R.string.password_change_sucess),
                                    buttonText = getString(R.string.understand),
                                    cancelable = true,
                                    clickListener = { (activity as DashboarActivity).redirectToLogin() }
                                )
                                sucessDialog.show(requireFragmentManager(), "sucess_otp_dialog")
                            } else {
                                showOtpError().also {
                                    (activity as DashboarActivity).redirectToLogin()
                                }
                            }
                        }

and the arquitecture of the clases in the app is this:

data class ValidateOtpResponse(
    @SerializedName("code")
    val code: String
) : Serializable, ResponseBase()

and their parent:

open class ResponseBase : Serializable

Have this any sense? Because I being using this kind of cast along the app, and it's works until now

So if you can throw some light into this issue, take thanks in advance !

CodePudding user response:

I try to apply the change which suggest Slaw, and Hakshay, and I've done something like this at repository level, which I guess it should works, but it doesn't:

Activity.class
  
(it.responseBase).let {resp ->
                            if ((resp as ValidateOtpResponse).code == "200") {
                                val sucessDialog = GenericDialog(
                                    context = requireContext(),
                                    icon = R.drawable.ic_tick_green,
                                    title = getString(R.string.change_password_title),
                                    subtitle = getString(R.string.password_change_sucess),
                                    buttonText = getString(R.string.understand),
                                    cancelable = true,
                                    clickListener = { (activity as DashboarActivity).redirectToLogin() }
                                )
                                sucessDialog.show(requireFragmentManager(), "sucess_otp_dialog")
                            } else {
                                showOtpError().also {
                                    (activity as DashboarActivity).redirectToLogin()
                                }
                            }
                        }

Repository.class

   override fun onResponse(
                call: Call<ValidateOtpResponse>,
                response: Response<ValidateOtpResponse>
            ) {
                /**
                 * We set as response the code, which tells if the call works: 200: OK - 400: KO
                 */
                if(response.isSuccessful){
                    response.let {
                        var value: WrapperResponse<ValidateOtpResponse> = WrapperResponse(response.body() as ValidateOtpResponse, ErrorBase(ErrorBase.ErrorType.NON_ERROR))
                        (value.responseBase as ValidateOtpResponse).code = response.code().toString()
                        Log.d("pass", "code after change: ${(value.responseBase as ValidateOtpResponse).code}")
                        validateChangePasswordOtpLD.postValue(value)
                    }
                }else{
                    var error : ErrorBase
                    response.let {
                        error = ErrorBase(it.errorBody()!!.string(), it.code(), ErrorBase.ErrorType.STRING)
                    }
                    validateChangePasswordOtpLD.postValue((WrapperResponse(ResponseBase(), error)))
                }
            }
            override fun onFailure(call: Call<ValidateOtpResponse>, t: Throwable) {
                validateChangePasswordOtpLD.postValue(WrapperResponse(ResponseBase(), ErrorBase()))
            }

I try to set the response from the API, and then modify the atribute of the response before set to the LD.

Although this changes, I still getting the cast exception when I try to recover the data into the activity.

CodePudding user response:

Your response is of type ResponseBase which is the superclass. You are trying to cast it to type ValidateOtpResponse which is a subclass. You would not be able to cast an object of superclass into an object of the subclass.

For example: snippet for examples

You need to fetch the response of type ValidateOtpResponse.

  • Related