Q:

OOP: Calling a public method within the same class

I was reading some article about collision avoidance systems in cars when my programmer mind led me to think of that concept in the object-oriented way, and it made me wonder if those systems respect the object-oriented programming model.
Being mainly a Java developer, I transposed this problem in a Java environment and it raised a particular question: does calling a public method within the same class (in a non-static context) respect and follow the object-oriented way?
I mean, take this brief hypothetical Car class:
public class Car {
    // Class attributes.

    // Constructors.

    public void accelerate(final double amplitude) {
        // Accelerate according to the amplitude.
    }

    public void brake(final double amplitude) {
        // Brake according to the amplitude.
    }

    // Other useful methods.

    private void collisionPreventionActions() {
        // Some actions.

        brake(100.0);

        // Some other actions.
    }
}

Suppose some Thread is responsible of detecting a collision and take actions when it does detect a collision, and one of those actions would be braking. Obviously the brake(...) method becomes an interesting choice, but doesn't that break the object-oriented way of doing things? It's not just the brakes though. What if the collision avoidance system in this class  used the steering wheel instead to avoid the accident? I find it weird that the car would be using its own input from an internal point of view...
On a more general scope, suppose you have a generic object, which I like to see as a black box. The public methods would be the equivalent of levers on that black box that would control its behaviour. Calling a public method within this object would mean that the black box would activate its own levers from its internal mechanism.
I ask because I know it's legal in Java to do so, and that I've seen public methods being called within the same class numerous times in my life, but it being legal doesn't necessarily mean that it's the proper OO way of doing it.
Does using public methods within the same class in a non-static context follow the rules of object-oriented programming and encapsulation? If not, what would be the proper way of doing it or what could be the workaround?

A:

There is nothing wrong with this choice from the OOP perspective: it is perfectly fine for a method to perform things that require combinations of other methods.
In practice, though, a common approach would be to separate the functionality into a public and a private portions, like this:
public void brake(final double amplitude) {
    // check preconditions
    if (speed == 0) throw new IllegalStateException("cannot brake when standing");
    if (amplitude <= 0) throw new IllegalArgumentException("amplitude must be positive");
    // ... do other important checks
    doBrake(amplitude);
}
private void doBrake(final double amplitude) {
    // The real code goes here
}

Now your collisionPreventionActions could call doBrake instead of brake, assuming that you have checked all the necessary preconditions before making the call.
Note: doBrake should check its preconditions as well. However, rather than throwing exceptions when preconditions are not met, it can use assertions. The difference is that exceptions indicate a misuse of your public methods by others, while assertions indicate misuse of your encapsulated methods by you or someone else maintaining your code.

A:

No rules are violated when an object uses its own API. On the contrary, problems are likely to occur if a class has an API that can be overridden, but it fails to use that API internally.
As a trivial example, consider a non-final property accessor. An object could skip the accessor and read (or worse, write) fields directly. Suppose the accessor is overridden in a subclass to compute the property value using the field together with some other information from the subclass. Now the class is broken because it failed to honor its own contract.
Consider the (somewhat contrived) Point and OffsetPoint classes below. The derived class, OffsetPoint is written correctly, but it's inherited toString() method will not work as expected because the parent class, Point, wrongly fails to use its own accessors.
public class Point {

  private final int x, y;

  public Point(int x, int y) { this.x = x; this.y = y; }

  public int getX() { return x; }

  public int getY() { return y; }

  @Override
  public final String toString() { 
    /* Here's the bug; should be getX() and getY() instead of x and y */
    return String.format("(%d,%d)", x, y); 
  }

}

class OffsetPoint extends Point {

  private int dx, dy;

  OffsetPoint(Point point, int dx, int dy) { 
    super(point.getX(), point.getY());
    this.dx = dx; 
    this.dy = dy; 
  }

  @Override
  public int getX() { return super.getX() + dx; }

  @Override
  public int getY() { return super.getY() + dy; }

}

