tags:

views:

212

answers:

6

What I really want is a class with a generic constructor, and when a subclass' identical constructor is invoked, the subclass will have access to the same fields. Here is an example of what I would like to do:

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();
}

Obviously this won't work because FoobarCommand doesn't have direct access to Mediator med. So how would you access the med field? I don't want anyone else but the subclasses to have access to it, and "protected" is not an option because I want people to be able to create their own commands (which obviously would be outside the package).

+4  A: 

Declare Mediator Med as "protected" not private.

Lance Rushing
+2  A: 

you need to declare Mediator m protected in your mother class.

Moreover, in the exec() method in your subclass , you need to do m.doAFoobar() instead of med.doAFoobar() since med is not a member but a formal parameter of your constructor.

dweeves
+8  A: 

There is actually no such access modifier, strictly speaking. It's impossible to declare a field (or method/class, for that matter) only accessible to subclasses; the most restrictive modifier you can use is protected, which still allows access to other classes in the parent class' package.

But other than that niggle, protected is the way to go.

Edit: to clarify that protected is an option. To access a protected method, you must be either a subclass or within the same package; you don't have to be both. So a subclass of Command created in a different package would still be able to access (super).m.

Andrzej Doyle
You could check the type in the getters and setters. Its not an access modifier, but it should still achieve the desired result.
NickLarsen
+1  A: 
abstract class Command {
    protected Mediator m

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

    abstract void exec();
}

The class is not public, so it can only be extended by other classes in the same package and 'm' is protected so it can be accessed by derived classes.

Devon_C_Miller
+1  A: 

If you give med protected access it will be available to subclasses outside of the package.

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

willcodejavaforfood
+1  A: 

If you want a field to be accessible to only the class itself and any derived classes and other classes in that package, use the protected keyword. That's what it's there for, and it should still work even outside the package. Instead of having them call med.doFoobar();, they need to call m.doFoobar();

Alternately, you could create a protected (or public, even) get function. That way you expose the ability to get the mediator, but you don't have to let them overwrite it after it's declared.

However, what you want (unable to be read inside the package) is impossible in java keywording. But, since you're the one writing this particular package, couldn't you just not access it from inside the package? Or create your own package with just this file? There's no way to allow subclasses access and not allow classes in the package.

DivineWolfwood
you can't make it accessible to ONLY subclasses. It will also be visible to classes in the same package.
Point, I'll edit my answer.
DivineWolfwood