繁体   English   中英

Java类,其字段只能由其子类访问(没有getter / setter)?

[英]Java class whose fields are only accessible to its subclasses (without getters/setters)?

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

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。 那么你将如何访问med领域? 我不希望除了子类之外的任何人都可以访问它,并且“protected”不是一个选项,因为我希望人们能够创建自己的命令(显然这些命令在包之外)。

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

但除了那个niggle之外, protected是要走的路。

编辑 :澄清受保护一种选择。 访问受保护的方法,你必须一个子类同一包中; 你不必两个都是。 因此,在不同的包中创建的Command的子类仍然可以访问(super).m

声明Mediator Med为“受保护”而非私人。

你需要申报Mediator在你的母班保护。

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

abstract class Command {
    protected Mediator m

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

    abstract void exec();
}

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

如果您提供med受保护的访问权限,则它将可用于包外部的子类。

http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

如果希望只有类本身以及该包中的任何派生类和其他类可以访问字段,请使用protected关键字。 这就是它的用途,它甚至应该在包装之外工作。 他们不需要调用med.doFoobar();而是需要调用m.doFoobar();

或者,您可以创建受保护(或公共,甚至)get函数。 这样你就暴露了获取中介的能力,但你不必让它们在声明后覆盖它。

但是,在java keywording中,你想要的东西(无法在包中读取)是不可能的。 但是,既然你是编写这个特定软件包的人,那么你不能从包内部访问它吗? 或者只用这个文件创建自己的包? 没有办法允许子类访问,也不允许包中的类。

你可以做的是给子类一个名为完全相同的变量,然后使用构造函数和方法将它设置为超类

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更改将反映在超类中; 但是,如果类成员是基元,则不会发生这种情况。 (鉴于所有基元都具有等效的对象,如果稍微笨重,这可以解决)

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

暂无
暂无

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

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