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).

Reply via email to