Sealed Interfaceを調べてみた

更新: 2024/05/07, 作成: 2024/05/07

みなさんこんにちは、かじりです。Sealed Interfaceを調べてみました

permitsでインターフェースの実装を制御できる1

例えばこんな感じ。GPT-4に出力してもらった

public sealed interface Animal permits Cat, Dog {
    void makeSound();
}

final class Cat implements Animal {
    public void makeSound() { System.out.println("Meow"); }
}

final class Dog implements Animal {
    public void makeSound() { System.out.println("Woof"); }
}

例えばAnimalインターフェースでSheepクラスを実装しようとするとエラーになるらしい。

便利だな。

kotlinの公式によるとprivate constructorもかけるようだ [^private-constructor] [^private-constructor]: https://kotlinlang.org/docs/sealed-classes.html#constructors

sealed class IOError {
    // A sealed class constructor has protected visibility by default. It's visible inside this class and its subclasses
    constructor() { /*...*/ }

    // Private constructor, visible inside this class only.
    // Using a private constructor in a sealed class allows for even stricter control over instantiation, enabling specific initialization procedures within the class.
    private constructor(description: String): this() { /*...*/ }

    // This will raise an error because public and internal constructors are not allowed in sealed classes
    // public constructor(code: Int): this() {}
}

これも良さそうだな。役割を明確にできそう。

ファクトリーメソッドに使えそう。

rubyで書くとこう。

GPT-4に聞いて、replit.comで試した。

rubyだとprivate_class_methodで同じことができた。

class Product
  # コンストラクタをprivateにする
  private_class_method :new

  def self.create(name)
    new(name)
  end

  def initialize(name)
    @name = name
  end

  def display_name
    @name
  end
end

# 直接newは使えない
# product = Product.new('Test') # これはエラー

# クラスメソッド経由でインスタンスを作る
product = Product.create('Test')
puts product.display_name

話がそれるけど、シングルトンパターン

class SingletonObject
  @instance = new

  private_class_method :new

  def self.instance
    @instance
  end
end

puts SingletonObject.instance
puts SingletonObject.instance == SingletonObject.instance

SingletonObjectクラスのロード時に@instance変数がnewで初期化され、SingletonObject.instanceメソッドは毎回同じインスタンスを呼び出す。

Sealed Interfaceはこの記事のコメント欄2で気になった

脚注

  1. https://docs.oracle.com/en/java/javase/15/language/sealed-classes-and-interfaces.html#GUID-0C709461-CC33-419A-82BF-61461336E65F

  2. https://zenn.dev/koduki/articles/e9373cb78fcfef#discuss