简体   繁体   English

是否可以使用“密封方法”改进密封类?

[英]Is it possible to refine sealed classes with "sealed methods"?

I am playing with the preview sealed classes in java 15, and I was wondering why the keywords sealed and non-sealed only apply to classes and interfaces, but not methods (like other modifiers do).我正在玩 java 15 中的预览密封类,我想知道为什么关键字sealednon-sealed只适用于类和接口,而不适用于方法(像其他修饰符一样)。 I imagine it might be useful to decide specifically, which of the methods can be overridden by permitted subclasses.我想具体决定哪些方法可以被允许的子类覆盖可能是有用的。

An Example: I have a class Unit that has two subclasses Metric and Imperial , which both finally implement a basic functionality, here kind() .一个例子:我有一个 class 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"; }
}

This works.这行得通。 However, now I don't want to implement kind() in all subclasses, but provide an implementation that is final to all subclasses except the ones where overriding is permitted.但是,现在我不想在所有子类中实现kind() ,而是提供一个对所有子类都是最终的实现,但允许覆盖的子类除外。 In my mind this would look like this:在我看来,这看起来像这样:

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
}

Is there any way that I could achieve this with the new features or is there any other way I am missing?有什么方法可以通过新功能实现这一点,或者我还缺少其他方法吗?

You can do this with package-access classes.您可以使用包访问类来执行此操作。

Place all three classes in their own package, and delegate kind() to a package-private method—that is, a method which is neither public nor protected nor private.将所有三个类放在它们自己的 package 中,并将kind()委托给一个包私有方法——即既不是公共的也不是保护的也不是私有的方法。 This will allow only classes in that package to override it:这将只允许 package 中的类覆盖它:

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() is package-private, so only classes in the same package are able to override it. kindImpl()是包私有的,因此只有同一个 package 中的类才能覆盖它。

This works in any version of Java, regardless of whether sealed classes are in use.这适用于 Java 的任何版本,无论是否使用密封类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM