0

While working in intelliJ I was recommended to make a method be localized - by removing the access modifier. I realized I don't really know which modifier to use and when and would like some clarification.

I read this post: What is the difference between Public, Private, Protected, and Nothing?

and as that's for C#, although they're similar, I wanted to make sure it's not too different.

I also read the Javadoc post here: https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

and was still a bit skeptical.

Thanks in advanced!

Community
  • 1
  • 1
DeveloperRyan
  • 837
  • 2
  • 9
  • 22
  • 1
    Use private wherever possible. Use protected only if you are explicitly designing for inheritance. Nothing (package) allows for other classes in the same package to call the method, but not classes in a different package. Public, of course, allows anyone to invoke it. Use public sparingly. – KevinO Apr 15 '16 at 04:32
  • @neferpitou that's really just a copy of the chart at [link](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html). I was curious if there's a better way to explain it. – DeveloperRyan Apr 15 '16 at 04:34
  • Thanks, @KevinO this helped clarify it for me. Does this mean a public method can be easily modified from inside the main or another class? – DeveloperRyan Apr 15 '16 at 04:35
  • @Infinitylsx, I'm not sure what you mean by a method being modified. A method may be overridden in a subclass, but that can occur for public, protected or (in some cases) package methods. The reason to avoid public is that it creates a contract that must be maintained. Side note, a `final` method cannot be overridden. – KevinO Apr 15 '16 at 04:39
  • @KevinO Alright - I understand a slightly better now; it's likely I just need to use them more because I mostly just use public because that's what I've learned and felt comfortable with; with the only exception being that I frequently create my variables as private. – DeveloperRyan Apr 15 '16 at 04:43
  • 1
    To decide whether a method should be `public` or `private`: First, you need to think about what your class represents. Suppose you have a class `X`, and some other part of the code has an object of class `X`. What kinds of things should the other code be able to do with your `X`? Those are the methods you want to make public in `X`. Any other method you write in `X` will be a "helper" method that's only there to help one of the public methods work. That's an oversimplification that doesn't explain `protected` or "default", but it's where you need to start. – ajb Apr 15 '16 at 05:05
  • @ajb that's kind of what I meant above when I said that "the public methods could be modified inside the main and/or another class." Thanks for helping clear that up and make the basics easier to understand! – DeveloperRyan Apr 15 '16 at 05:16
  • Maybe you meant "the public methods could be _called_", or "invoked". "modified" would mean that main or another class could _change_ the method, and that's not possible. – ajb Apr 15 '16 at 05:17
  • @ajb thanks for the clarification. Just to be sure - if I wanted to call a method inside the _same_ class, I could use private. But to call it in a _different_ class I would want to use public correct? – DeveloperRyan Apr 15 '16 at 05:32
  • Essentially, yes. But be careful. If you have a `private` method in a class, and you start thinking "Hey, it would be useful to use that method in another class", you may be tempted to make it `public`. That's not really the right approach, though. It's best to think of your class conceptually--its purpose is to provide certain "features" or functionality to the users of the class. It shouldn't just let any old class reach in and use one of its helper methods. This is the encapsulation Craig is talking about. – ajb Apr 16 '16 at 04:05

1 Answers1

3

Access modifiers help with the OOP principle of encapsulation. If you create a well-written class anyone will be able to use it without knowing all the internal details of how it works. When you define a method as public any code that uses your class will have access to that method. You only want to expose methods the end user of your class will need. If it's a helper method that's does some internal calculation relevant only inside your class, declare it as private. It will cut down on the methods available to the end user and make your class much easier to use. Here's an example:

Public Class Car {
    private int speed;
    private float fuelNeeded;
    private float afRatio = 14.7;

    public void speedUp { speed++; }

    public void speedDown { speed--; }

    public float getFuelNeeded {
        calculateFuelNeeded(speed);
        return fuelNeeded;
    }

    private void calculateFuelNeeded (int speed) {
        // Do some complex calculation
        fuelNeeded = someValue / afRatio;
    }
}

Anyone who creates a Car object will have three methods available, speedUp, speedDown, and getFuelNeeded. calculateFuelNeeded is only used internally by the class, so there's no reason for the user to see it. This way they don't need to know how the amount is calculated, or when the method needs to be called, or what values it sets internally. They just get the value easily with getFuelNeeded();

When declaring variables, it is usually always correct to declare them private, having a public get() and set() method for any that need to be accessed from outside the class. The main reason for this is to prevent an outside user from setting the value something invalid. In our Car class, afRatio needs to be nonzero because we are using it as a divisor. If we declare it as public, a user could easily write this code:

Car car = new Car();
car.afRatio = 0;
someFloat = car.getFuelNeeded();

Of course this would cause our class to throw an ArithmeticException for divison by zero. However, if we did this:

private afRatio = 14.7;

public void setAfRatio(float ratio) {
    if(ratio <= 0)
        throw new IllegalArgumentException("A/F ratio must be greater than zero");
    afRatio = ratio;
}

This allows us to check user given parameters and ensure our variables don't get set to some invalid value.

Craig Parton
  • 118
  • 7