On Saturday, 12 May 2018 at 10:27:11 UTC, Walter Bright wrote:
The solution is:
private class MyClass { ... }
public final MyClassSealed : MyClass { }
Meaning other modules can use MyClassSealed but cannot derive
from it. Other classes inside the module can derive from
MyClass as required.
It is not. Other modules can use MyClassSealed - yes. Inheritance
is possible only im module - yes. But these are two different
classes still. If we have two of extending classes:
private class Parent {}
public final class Child1 : Parent {}
public final class Child2 : Parent {}
Then it is true that I can inherit Parent outside the module, but
I can't use it as well. In this case I can't create an array
(other then Object[]) that can hold both Child1 and Child2
outside the module.
What I want is to see the supertype *everywhere* and be able to
use it for example to create an array of Parents, but not be able
to create Child3 : Parent elsewhere then in the module where
Parent resides.
public final class ParentSealed : Parent {}
won't help - it will be just the same as two ChildX classes and
still won't have a *visible* supertype other then Object with
them.
What I am trying to do is:
/* foo.d */
module foo;
sealed class Parent {}
final class Child1 : Parent {}
final class Child2 : Parent {}
/* bar.d */
module bar;
import foo;
static this
{
Parent[] twoParents = [new Child1(), new Child2()]; //
Parent is still visible
}
class Child3 : Parent {} // ERROR: Parent is sealed and cannot
be extended outside module foo
I don't think that it is possible to rewrite this code without
sealed, but still having Child3 illegal and the Parent[] array
creatable in the module bar.
Another example - taken directly from Scala. In Scala optionals
are defined via a set of classes ("[T]" is Scala's version for
Java's "<T>"):
sealed abstract class Option[T] {}
final case class Some[T] extends Option[T] {}
object None extends Option[Nothing] {}
For the sake of simplicity let's don't dive in how "case class"
and "object" are different from typical classes. Also let's
assume that Nothing extends T (in fact Scala's Nothing extends
every possible type)
You can declare an Option[Int] variable everywhere and assign
Some(value) or None to it. All three classes are visible from
everywhere, but as Option is sealed, you can't create
class OnlyOnMonday[T] extends Option[T] {}
in the other module (effectively nowhere, as Option is a part of
the standard library).