2

我正在使用 java 15 中的预览密封类,我想知道为什么关键字sealedandnon-sealed仅适用于类和接口,而不适用于方法(就像其他修饰符一样)。我想具体决定哪些方法可以被允许的子类覆盖可能很有用。

一个例子:我有一个类Unit,它有两个子类MetricImperial,它们最终都实现了一个基本功能,在这里kind()

public abstract sealed class Unit permits Imperial, Metric {
    public abstract String kind ();
}

public abstract non-sealed class Imperial extends Unit {
    @Override
    public final String kind() { return "imperial"; }
}

public abstract non-sealed class Metric extends Unit {
    @Override
    public final String kind() { return "metric"; }
}

这行得通。但是,现在我不想kind()在所有子类中实现,而是提供一个对所有子类都是最终的实现,除了允许覆盖的子类。在我看来,这看起来像这样:

public abstract sealed class Unit permits Imperial, Metric {
    // this is not supported
    public sealed String kind () permits Imperial {return "easy"; }
}

public abstract non-sealed class Imperial extends Unit {
    @Override
    public final String kind() { return "oh my god"; }
}

public abstract non-sealed class Metric extends Unit {
    // should not be possible to override kind() here or in any subclass
}

有什么方法可以通过新功能实现这一目标,还是我缺少其他方法?

4

1 回答 1

1

您可以使用包访问类来做到这一点。

将所有三个类放在它们自己的包中,并委托kind()给一个包私有方法——即,一个既不是公共的也不是受保护的或私有的方法。这将只允许该包中的类覆盖它:

package com.example.units;

public abstract sealed class Unit permits Imperial, Metric {
    public final String kind () {
        return kindImpl();
    }

    String kindImpl() { return "easy"; }
}

package com.example.units;

public abstract class Imperial extends Unit {
    @Override
    String kindImpl() { return "imperial"; }
}

kindImpl()是包私有的,所以只有同一个包中的类才能覆盖它。

这适用于任何版本的 Java,无论是否使用密封类。

于 2020-12-02T13:10:19.963 回答