其字段仅可由其子类访问的Java类(没有getter/setter)?

其字段仅可由其子类访问的Java类(没有getter/setter)?,java,Java,我真正想要的是一个具有泛型构造函数的类,当调用子类的相同构造函数时,子类将可以访问相同的字段。下面是我想做的一个例子: public abstract class Command{ private Mediator m public Command(Mediator med){ m = med; } abstract void exec(); } public class FoobarCommand extends Command{ p

我真正想要的是一个具有泛型构造函数的类,当调用子类的相同构造函数时,子类将可以访问相同的字段。下面是我想做的一个例子:

public abstract class Command{
    private Mediator m

    public Command(Mediator med){
       m = med;
    }

    abstract void exec();
}

public class FoobarCommand extends Command{
    public FoobarCommand(Mediator med){
        super(med);
    }

    public void exec(){
        med.doAFoobar()
    }
 }

public static void main(String[] args){
    Mediator m = new Mediator();
    Command c = new FoobarCommand(m);
    c.exec();
}

显然,这是行不通的,因为FoobarCommand不能直接访问Mediator med。那么你将如何进入医学领域?我不希望除了子类之外的任何人都可以访问它,而且“protected”不是一个选项,因为我希望人们能够创建自己的命令(这显然在包之外)。

将Mediator Med声明为“protected”而不是private。

您需要在母类中声明Mediator m protected


此外,在子类中的exec()方法中,需要执行m.doAFoobar()而不是med.doAFoobar(),因为med不是构造函数的成员,而是构造函数的形式参数。

严格来说,实际上没有这样的访问修饰符。不可能只声明子类可以访问的字段(或方法/类);您可以使用的限制性最强的修饰符是
protected
,它仍然允许访问父类包中的其他类

但除此之外,
protected
是一条出路

编辑:阐明受保护是一个选项。要访问受保护的方法,您必须是子类或在同一个包中;你不必两者兼而有之。因此,在不同包中创建的
命令
的子类仍然可以访问
(super).m


该类不是公共类,因此只能由同一包中的其他类扩展,并且“m”受保护,因此可以由派生类访问。

如果您授予med protected访问权限,则该类将可用于包外的子类


如果您希望字段只能由类本身以及该包中的任何派生类和其他类访问,请使用protected关键字。这就是它的目的,即使在包装之外,它也应该仍然有效。而不是让他们调用med.doFoobar();,他们需要调用m.doFoobar()

或者,您可以创建一个受保护(或公共,甚至)的get函数。通过这种方式,您可以公开获取中介的能力,但不必让中介在声明后覆盖它


但是,您想要的(无法在包中读取)在java关键字中是不可能的。但是,既然你是编写这个特定包的人,你就不能不从包内访问它吗?或者仅使用此文件创建您自己的包?没有办法允许子类访问,也不允许包中的类。

您可以给子类一个名为完全相同的变量,然后使用构造函数和类似的方法将其设置为等于超类

public abstract class Command{
    private Mediator m

    public Command(Mediator med){
       m = med;
    }

    abstract void exec();
}

public class FoobarCommand extends Command{

    private Mediator m;

    public FoobarCommand(Mediator med){
        super(med);
        m = med;
    }

    public void exec(){
        m.doAFoobar()
    }
 }

public static void main(String[] args){
    Mediator m = new Mediator();
    Command c = new FoobarCommand(m);
    c.exec();
}
然而,这是有限的,它可以做什么。由于
m
是对象引用,子类中对
m
的更改将反映在超类中;但是,如果类成员是基元,则不会发生这种情况。(假设所有基本体都有一个等效的对象,如果稍微笨重,可以解决这个问题)


子类还必须直接接收引用,因为引用的副本存储在那里。对于抽象超类,这是可以的,因为你保证是一个子类,但在下面,你必须小心处理数据。

我不理解你为什么不使用Option,因为“exec”似乎是指挥官的方法,而不是调解人的方法。为什么不让exec的功能成为中介的方法(声明为中介接口的一部分)?然后,您就可以拥有一个通用的命令对象,其中包含一个用于中介的setter和一个多态exec方法。我一直有点睡眠不足,我意识到我一直想要“保护”,甚至不应该问这个问题:-!您可以在getter和setter中检查类型。它不是一个访问修饰符,但仍然应该达到预期的效果。你不能让它只对子类访问。它也将对同一包中的类可见。是的,但也可以由同一包及以上的类访问,这不是需要的行为。
public abstract class Command{
    private Mediator m

    public Command(Mediator med){
       m = med;
    }

    abstract void exec();
}

public class FoobarCommand extends Command{

    private Mediator m;

    public FoobarCommand(Mediator med){
        super(med);
        m = med;
    }

    public void exec(){
        m.doAFoobar()
    }
 }

public static void main(String[] args){
    Mediator m = new Mediator();
    Command c = new FoobarCommand(m);
    c.exec();
}