Or is there some other clever way to solve this?
# getting-started
e
Or is there some other clever way to solve this?
d
You certainly could used a sealed class with inner classes to solve it. You might also want to look at https://kotlinlang.org/docs/reference/visibility-modifiers.html for what visibilities can be seen by subclasses if you aren't familiar with them.
If your base class is abstract it won't be able to be directly instantiated, if you weren't already marking it abstract.
e
Hm, okay. Its
private sealed class
for now, as I only want to see it used in this file, and in this specific way
What am I doing wrong here since I dont see the values in Product?
d
Software
doesn't automatically extend from
Product
. You need to explicitly do that.
e
Ah, thanks. That solved it!
Struggling a bit with initializing the subclass now.
Constructor of inner class can be called only with receiver of containing class
Not sure I follow what this means
d
Can you share the line that's not working?
e
Copy code
private sealed class Product(val a: Int) {
        inner class Software(val b: String) : Product(a)
    }
    
    private fun test() {
        val c = Product.Software("S", 1)
    }
d
Oh, don't mark it an inner class. It should just be
class software
e
That turns the
a
invisible for the
Software
d
inner class
means that it's capturing all of the properties in the containing class. It's what a non-static inner class does in Java, if you're familiar with Java.
Yeah, but if you need an
a
it should be a parameter to
Software
.
If you want to do it with the
inner class
then you need to do
Product(1).Software(...)
I believe.
Because that parameter has to come from somewhere, after all 🙂
e
Oh… Hm. So, in this context a
Product
has some values that does not really care whether it is software or not. I thought it would make sense to place these values on the
Product
class, and not the subclass
Oh I see what you mean now
Like this, right?
d
Yep 🙂 If you're going to use the
inner class
syntax, then what you're actually doing it creating an instance of
Product
then creating a
Software
which extends
Product
but has a different
Product
as its outer class. This way is cleaner because the only
Product
is the one that's the super-class of
Software
.
e
Lets say I did decide to go with the inner approach. How would I initialize an instance of Product.Software somewhere?
d
Well you have to have an instance of
Product
so for example:
Copy code
val p = Product(1)
val s = p.Software("a")
(similar syntax exists in Java for this case, it's just rarely used).
e
Aha okay, so that means inner classes and sealed classes dont really work together, as sealed classes prevent initializing the super class, and inner subclasses demands it?
d
Hm, I hadn't tried to use them together before, but I think that's correct. It's possible there should be a compiler error message preventing it, or at least warning about it.
e
Reason I am asking is because this becomes quite verbose as I have to list the super arguments twice
It works well for smaller classes like this example
but if the super has values
a
through
e
you have a lot of stuff to list in both the
software
constructor and the
: Product()
constructor
d
Hm, well another way you could look at this is making
Product
an interface, and passing product as a parameter to your
Hardware
or
Software
classes, creating some kind of interface for
Product
and then using class delegation... ie:
class Software(a: Int, product: Product): ProductInterface by product
That moves the code repetition to creating
ProductInterface
rather than having more constructor parameters (assuming you have so many constructor parameters you're concerned). The problem is that maintaining
ProductInterface
can become tedious depending on how many methods it has, and how often you add/remove methods.
j
"I have a class
Product
that I do not want to see initialized by itself, but as one of its subclasses
Hardware
or
Software
. The two subclasses has unique values of their own, but the
Product
class has a few shared values that both hardware/software-products will have" didn't you simply describe an abstract
Product
class with
Hardware
and
Software
concrete subclasses? i must be missing something though like this: https://pl.kotl.in/2JD_Qz4WF