0

How can I create an instance of InfoA that contains also title. Do I need to modify the classes?

Can't specify the title.

Also, do I need to create setters for it? To not access with the _

val info = InfoA(_subtitle = "SUBTITLE", title = ...)
  open class Info(
     open val action: Action = Action(),
     open val title: String? = ""
  ) {
    fun hasAction(): Boolean = action.hasAction()
  }

  class InfoA(
    private val _subtitle: String? = "",
    private val _image: String? = "",
    private val _backgroundImage: String? = "",
    private val _backgroundColor: String? = null,
    private val _foregroundColor: String? = null,
    private val _borderColor: String? = null
  ) : Info() {

    val subtitle: String
      get() = _subtitle.orEmpty()

    val image: String
      get() = _image.orEmpty()

    val backgroundImage: String
      get() = _backgroundImage.orEmpty()

    val backgroundColor: Int?
      get() = if (_backgroundColor != null) convertRgbStringToColorInt(_backgroundColor) else null

    val foregroundColor: Int?
      get() = if (_foregroundColor != null) convertRgbStringToColorInt(_foregroundColor) else null

    val borderColor: Int?
      get() = if (_borderColor != null) convertRgbStringToColorInt(_borderColor) else null
  }

1 Answer 1

2

As the code is written, title is a val, so it can't be changed from its initial value — which is empty string if (as in the case of InfoA) something calls its constructor without specifying another value.

If it were changed to be a var, then it could be changed later, e.g.:

val info = InfoA(_subtitle = "SUBTITLE").apply{ title = "..." }

Alternatively, if you want to keep it a val, then InfoA would need to be changed: the most obvious way would be to add a title parameter in its constructor, and pass that up to Info:

class InfoA(
    title: String? = "",
    // …other fields…
) : Info(title = title) {

Note that this way, InfoA can never use Info's default value for title, so you may need to duplicate that default in InfoA's constructor.

The need to duplicate superclass properties in a subclass constructor is awkward, but there's currently no good way around it.  (See e.g. this question.)  If there are many parameters, you might consider bundling them together into a single data class, which could then be passed easily up to the superclass constructor — but of course users of the class would need to specify that.  (Some people think that having more than a few parameters is a code smell, and that bundling them together can often improve the design.)

Sign up to request clarification or add additional context in comments.

2 Comments

@PraveenP. Thanks for accepting my answer.  (But please note that on this site it's usually better to wait for a day, to give people who are busy or in other time-zones a chance.  Impossible as it may seem, someone might theoretically be able to write an even better answer than mine :-)
Also, I realise I didn't address your point about setters: those would only be possible if you changed the vals to vars; but it looks like you wouldn't need to override both getters and setters to get the behaviour you want.  Though you shouldn't be afraid of nullable values; Kotlin is well set up to handle them safely, so in a case like this I'd probably look at using only the ‘bare’ properties defined in the constructor, without providing non-nullable versions at all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.