views:

3463

answers:

11

From what I have gathered, I want to force a class to use particular private fields (and methods) I need an abstract class because an interface only declares public/static/final fields and methods. Correct??

I just started my first big java project and want to make sure I'm not going to hurt myself later :)

A: 

This is correct. But it is not necessarily an either-or decision, you can combine the advantages of interfaces and abstract classes by providing a skeletal implementation along with your interface. You can find a very interesting description of this approach in Effective Java, 2nd Ed., Item 18 ("Prefer interfaces to abstract classes").

Fabian Steeg
+3  A: 

Private fields and methods cannot be used by subclasses (except if they are also inner classes). You could make them protected, however.

Michael Myers
+1  A: 

That's correct. Interfaces are for public consumption. And private implementation needs to be in an abstract (or concrete) class.

Jekke
+1  A: 

If you ever find yourself guessing which one to choose I's suggest to err on the side of Interfaces - It's better to have an interface that should have been an abstract class than the other way around.

Simon Groenewolt
+11  A: 

You don’t want to force the use of certain private fields or methods. In general you don’t care about the implementation, you care about the interface. So define a couple of methods in a couple of interfaces (depending on how much you need) and define classes that implement them. This will probably hurt you the least in the future.

Bombe
+1 i am astounded that there are so many literal answers to this question, and your is the only one to address the bad assumption behind the question.
Steven A. Lowe
SO rule of thumb: read the 2nd answer.
mitjak
+1  A: 

An interface defines just that - an interface (contract) with the world outside the implementing class. The public methods of a (abstract or not) superclass do the same. You shouldn't try to require subclasses to have certain private members - you are trying to specify implementation which is what OOP is all about avoiding.

You use an abstract class when you want to define some shared behaviour in a superclass - but that class can't stand on its own (it needs to be subclassed). It may be that the shared behaviour needs some state of its own - in which case it can define private fields, and it may also have private methods which only it can use.

Even if you inherit from an abstract class, you won't be able to access its private fields/methods.

Draemon
A: 

Interfaces define a contract for behavior. That's what they need to be about, not attributes.

duffymo
A: 

If you want the subclass to define specific methods, using an interface will do the trick. As others have said, it's not so much about how the subclass does it, just the fact that it will do it.

Chris Stewart
+7  A: 

It's fairly common to provide both, so that you end up with:

public interface Sendable {
    public void sendMe();
}

and

public class AbstractSender implements Sendable {
    public abstract void send();

    public void sendMe() {
        send(this.toString());
    }
}

That way, anyone who is happy with the default implementation in the abstract class can quickly subclass it without rewriting a lot of code, but anyone who needs to do something more complex (or who needs to inherit from a different base class) can still implement the interface and be plug-and-play.

Richard Campbell
dont you want AbstractSender implements Sendable.
Milhous
Yes. Corrected. Really, I want a less contrived example, but nothing immediately came to mind.
Richard Campbell
+1  A: 
I want to force a class to use particular private fields (and methods)

This part of your question is questionable: why do you think you want to do this?

private members are not visible to subclasses, and interfaces define the public interface, so your only choice would be to use an abstract class...but I cannot think of any reason why anyone would ever want to do this

Steven A. Lowe
A: 

If you want a class to use certain fields or methods of another class, you could declare them as protected.

    public abstract class A {

      protected Object thing;
    }

can be accessed by another class in the same package (could be extending class A, or not)

A a = new A();
a.thing.toString();

It's not really "forcing" another class to use it though, more like "enabling".

Lars Andren