Sealed classes - would you want them in D?

Piotr Mitana the.mail.of.mi2 at gmail.com
Sat May 12 15:18:52 UTC 2018


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



More information about the Digitalmars-d mailing list