How to use a private method in Java - java

I am given a class that has a private method say setCoors(int x, int y). The constructor of that class has the setCoors in it too. In a different class, I want to have a method setLocation which calls setCoors. Is this possible?
New Question:
If I am not allowed to set the method to public, is this possible?
public class Coordinate{
public Coordinate(int a, int b){
setCoors(a,b)
}
private void setCoords(int x, int y)
}
public class Location{
private Coordinate loc;
public void setLocation(int a, int b)
loc = new Coordinate(a,b)
}

The best and most helpful answer depends on the context of the question, which is, I believe, not completely obvious.
If the question was a novice question about the intended meaning of private, then the answer "no" is completely appropriate. That is:
private members of A are accessible only within class A
package-private members of A are accessible only within classes in A's package
protected members of A are accessible only within classes in A's package and subclasses of A
public members of A are accessible anywhere A is visible.
Now, if, and okay maybe this is a stretch (thank you Brian :) ), that the question came from a more "advanced" context where one is looking at the question of "I know private means private but is there a language loophole", then, well, there is such a loophole. It goes like this:
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
class C {
private int x = 10;
private void hello() {System.out.println("Well hello there");}
}
public class PrivateAccessDemo {
public static void main(String[] args) throws Exception {
C c = new C();
List<Field> fields = Arrays.asList(C.class.getDeclaredFields());
for (Field f: fields) {
f.setAccessible(true);
System.out.println(f.getName() + " = " + f.get(c));
}
List<Method> methods = Arrays.asList(C.class.getDeclaredMethods());
for (Method m: methods) {
m.setAccessible(true);
m.invoke(c);
}
}
}
Output:
x = 10
Well hello there
Of course, this really isn't something that application programmers would ever do. But the fact that such a thing can be done is worthwhile to know, and not something that should be ignored. IMHO anyway.

No, private means the method can only be called inside of the Class in which it is defined. You will probably want to have setLocation create a new instance of the class setCoords resides in, or change the visibility on setCoords.
EDIT: The code you have posted will work. Just be aware that any instance of the Location class will be bound to its own Coordinate object. If you create a new Coordinate object somewhere else in your code, you will be unable to modify its internal state. In other words, the line
Coordinate myCoord = new Coordinate(4, 5);
will create the object myCoord which will forever have the coordinates 4 and 5.

private means it's private
If you want other classes to call it, maybe you shouldn't make it private?

No private methods can't be accessed outside the class in which they are defined

Kid-doing-homework: the answer is no. Guy-requiring-some-crazy-work-around-for-his-job: the answer is yes. Far more importantly though, Your setCoors method should not take int arguments. It should take two SilverBullet objects.

private means you can only access it inside the class defined.

Related

Creating Inner Classes and using them (understanding some code)

I have been reading through some documentation on inner classes, and am currently reading my textbook, where I have found some good knowledge on using Inner classes. For starters I would like to consider the following example and just make sure I am understand things correctly. For reference I have read the follwing Inner Classes Documentation and have read a couple of SO questions. Hopefully someone can guide me through the following.
import java.util.ArrayList;
public class Gearbox {
private ArrayList<Gear> gears;
private int maxGears;
private int currentGear;
public Gearbox(int maxGears)
{
this.maxGears = maxGears;
this.gears = new ArrayList<Gear>();
Gear neutral = new Gear(0,0.0);
this.gears.add(neutral);
}
public class Gear
{
private int gearNumber;
private double ratio;
public Gear(int gearNumber,double ratio)
{
this.gearNumber = gearNumber;
this.ratio = ratio;
}
public double driveSpeed(int revs){
return revs * ratio;
}
}
}
In the main.java
public class Main {
public static void main(String [] args)
{
Gearbox ford = new Gearbox(6);
Gearbox.Gear first = ford.new Gear(1,20);
System.out.println(first.driveSpeed(10));
}
}
What I am kind of confused about is the notation to actually use some stuff from the nested class. For example
Gearbox ford = new Gearbox(6);
Here we make a ford object belonging to the class of Gearbox, which passes in a value of 6 to maxGears.
Next we have Gearbox.Gear first = ford.new Gear(1,20);, Here is where I am kind of confused on what is really going on. Does the .Gear let the compiler know that Gear is an inner class within Gearbox? If so, why is the next statement ford.new Gear(1,12.3)?
Wouldn't something like Gearbox.Gear first = new ford.Gear(1,12.3); make more sense?
Next we have
Gearbox.Gear first = ford.new Gear(1,20);
Here is where I am kind of confused on what is really going on. Does the .Gear let the compiler know that Gear is an inner class within Gearbox?
Yes ... sort of. Actually, it is saying "I am talking about the Gear class that is declared in Gearbox. It is not necessarily an inner class: it could be a nested class.
If so, why is the next statement ford.new Gear(1,12.3) ?
An instance of an inner class must be created in the context of an instance of its enclosing outer class. The ford.new Gear(...) is saying create the new Gear instance in the context of the Gearbox instance that ford refers to.
(If that still doesn't make sense, reread the above paying special attention to usage of the the word "instance". An instance of a class is an object .....)
As #Thilo points out, making Gear an inner class (rather than a nested class) here does not really achieve anything. It would probably be better to a redeclare Gear as
public static class Gear ...
and then you would not need to qualify the new with an instance of the Gearbox class.
Your inner class is not static, which means it belongs to a concrete instance.
Gearbox.Gear first = new ford.Gear(1,12.3);
Means that you create a Gear for instance ford.
Here you can read some more about inner class and about difference of static and non-static inner classes.

Should I declare variables in the class, if the class has only a constructor?

Let's say I have a class:
public class Foo {
private int x;
private int y;
public Foo(int x, int y) {
this.x = x;
this.y = y;
/**
* here comes a lot of code within this constructor
* that uses these x and y variables.
*/
}
}
I understand, that if I had some other methods in this class that would use the x and y variables, I should have copied the constructor's arguments into the fields like I did above, but what if I don't have any other methods but only the constructor? Should I still create the fields or my class should look like this:
public class Foo {
public Foo(int x, int y) {
/**
* here comes a lot of code within this constructor
* that uses these x and y variables.
*/
}
}
What is the right style?
UPDATE
Sorry, I was wrong by thinking that there is a some general pattern of doing this, that's why I gave some idle example. I still will not copy-paste my code, because the project is too big and a single class out of context will not make any sense. But here's a more specific example:
import javax.swing.JLabel;
import javax.swing.JPanel;
public class InformationPanel extends JPanel {
private JLabel nameLbl = new JLabel();
public InformationPanel(Student student) {
nameLbl.setText(student.getName());
this.add(nameLbl);
}
}
So in this case should I have a local field
private Student student;
And then:
this.student = student;
Or I shouldn't?
A constructor is used to initialize the state of an object. Based on your question, your object has no state.
Your constructor accepts some parameters which are only used inside the constructor. Your constructor doesn't produce any output. Although I don't know what logic you have inside this constructor, it seems like you are using the constructor as if it was a static method. Why not put your logic in a static method?
The first is the preferred style. However, the answer for this case is probably: use a static method, don't use a constructor.
If you want just the functionality that's encoded in the constructor method, then a static method is the way to go.
As a constructor is used to create a new instance of a class, which combines functionality (via other methods) and state (via fields) it's hard to see how a stateless, methodless instance would be much use. Hence the guess on my part is that what you're after is:
public class Foo {
public static void doSomething(int x, int y) {
/**
* here comes some code within this method
* that uses these x and y variables.
*/
}
}
The last part being - don't put a lot of code in a single method, unless it really belongs there. Think modularly and decompose the method into parts each of which may be tested.
You should not store the values in fields if they are only used in the constructor.
However, more importantly what you are doing is not appropriate for a constructor. As the resulting object created seems fairly useless.
Don't see why you need a class to achieve what you are trying to do. Depending on your use case it either should be a method in another class or a Utility Class containing static methods. But it all depends on what you are trying to do or the context.

Class-specific method visibility

Is there some object oriented thing that you can call some methods from certain classes, but not all of them? Is there something like that which is similiar to protected?
Say you have a method void foo() and you want it to be available to the programmer in a few types of classes (perhaps something like using Type variables (to specify: T type). Now, perhaps is there some way, without inheriting the class with foo() in it, or making an interface, to specify which classes or types of classes have access to that method?
I would guess this could be like multiple-inheritance and polymorphism? But I still want only the class and certain classes to access the method without changing the visibility of the method. I want the visibility to be class-specific.
Here is an example:
class A sees foo() as private, but only that class sees it as private.
class B sees foo() as public/protected, but only that class sees it as public.
The method type would be default.
I guess what is easier to ask and answer to is: "Is there class-specific visibility?"
There is something like you are asking for in C++, it is called friend classes. Nevertheless, that concept is not supported by Java:
'Friends' equivalent for Java?
A second option is to use code reflection to access a class private members but it isn't such a clean solution and only works for protected elements:
public class C1 {
public C1()
{
x = "Hello Word!";
}
protected String x;
}
At a different class's method:
String val = (String)obj.getClass().getDeclaredField("x").get(obj);
System.out.println("val: " + val);
EDIT: After making a little bit of research I found it is possible even to access private members:
Field field = obj.getClass().getDeclaredField("x");
field.setAccessible(true);
String val = (String)field.get(obj);
field.setAccessible(false);
No, there's nothing like that in Java.
The closest you've got is putting classes within the same package, at which point they have access to any members which don't specify any access modifier. You can't specify particular classes though.
Another option which is appropriate in some cases is to use nested classes:
class Outer {
private static class Inner {
}
}
Here Outer and Inner have access to each other's private members.
Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
thats your lot, there are not any other access modifiers.
With a little sleight of hand you can make one class seem to be two different classes:
// An interface.
interface A {
public void a ();
}
// Another interface.
interface B {
public void b ();
}
// Deliberately NOT stating we implement either A or B but actually we implement both.
class C {
public void a () {
}
public void b () {
}
}
// Pick either implementation from C and tell the world about it.
class D extends C implements A {
// Do nothing - already done by C.
}
class E extends C implements B {
// Do nothing - already done by C.
}
public void test() {
A d = new D();
B e = new E();
}
Here D and E are actually identically functioned objects because they are both actually Cs. However, as they are created they are made to seem to be A or B which are two different interfaces.
Unfortunately we cannot hide the fact that they both extend C but a little further sleight of hand and we can do that too with a Factory.
// Hide the guts of it all in a factory.
static class Factory {
// Make sure you MUST use the factory methods.
private Factory () {
}
// Construct an A.
public static A newA () {
return new D();
}
// Construct a B.
public static B newB () {
return new E();
}
}

Why am I able to call private method?

I should not be able to invoke a private method of an instantiated object. I wonder why the code below works.
public class SimpleApp2 {
/**
* #param args
*/
private int var1;
public static void main(String[] args) {
SimpleApp2 s = new SimpleApp2();
s.method1(); // interesting?!
}
private void method1() {
System.out.println("this is method1");
this.method2(); // this is ok
SimpleApp2 s2 = new SimpleApp2();
s2.method2(); // interesting?!
System.out.println(s2.var1); // interesting?!
}
private void method2() {
this.var1 = 10;
System.out.println("this is method2");
}
}
I understand that a private method is accessible from within the class. But if a method inside a class instantiate an object of that same class, shouldn't the scope rules apply to that instantiated object?
Can static method like main access the non-static member of the class, as given in this example ?
Your main method is a method of SimpleApp, so it can call SimpleApp's private methods.
Just because it's a static method doesn't prevent it behaving like a method for the purposes of public, private etc. private only prevents methods of other classes from accessing SimpleApp's methods.
Because main is also a member of SimpleApp.
See below chart
Access Modifiers
**Same Class Same Package Subclass Other packages**
**public** Y Y Y Y
**protected** Y Y Y N
**no access modifier** Y Y N N
**private** Y N N N
As your method is inside car it's accessible based on above thumb rule.
From the Java Tutorial:
private modifier—the field is accessible only within its own class
The main method is inside the same class as the private method and thus has access to it.
private means "only stuff in this class can mess around with it". It doesn't mean "only this instance can call its methods", which seems to be what you're expecting. Any code in SimpleApp can use anything in any SimpleApp. The alternative would be to break encapsulation -- how would you make a proper equals method, for example, that didn't require access to another instance's fields, without making those fields protected or even public or requiring getters for data that should only be available inside the class?
The call you issue is from within the same class where your private method resides. This is allowed. This is the way 'private' is defined in java.
In the program, we created two instances of the class by using which we called two private methods. It's a kind of interesting to see this works is that this is the way we used to call public or default methods outside its class using object reference. In this case, it's all done inside the class definition, so it's valid. The same code put outside the class will result in error.
Because the private scope limits access to the class defining the method, and your main happens to be in the same class.
private modifier—the field is accessible only within its own class.
See Access Modifiers in the Java Documentation.

basic exercise in java

I have two classes A and B as follows:
public class A {
private int salary = 0;
protected void calculate() {
salary = 400;
}
protected A() {
calculate();
}
}
public class B extends A {
private int salary = 0; // (1)
protected void calculate() {
System.out.println("calculating salary...");
salary = 700;
}
public static void main(String[] args) {
System.out.println(new B().salary); // (2)
}
}
Consider line (2): I don't understand why new B().salary is valid because the specifier of salary in line (1) is private. Could you help me explain it?
You can access B.salary because your code is executing inside the class B.
A common misconception of private (or all access modifiers, in fact) is that it acts on a per-object basis, which is not true. A private field is private to the whole class. So every instances of B can access the salary field of each other B object. Even static code in B can do that.
Also note that you're needlessly complicating matters by introducing the class A: it has no actual effect on your example, you can simply leave it out.
I don't see any private constructor of B so new B() is valid + the private field is accessible within same class
private applies to things outside the class definition, everything inside the class definition can see them.
main is a (static) member of B, so it can see private members.
Every class has access to its private parts.
It is valid since main is inside the B class, which means all fields (even private) are visible to it.
If you move main to another class, it will not be valid anymore.
Private fields can be accessed only from within the same class. So salary can only be accessed from class B.
Since your main method is in class B, you can access it.
salary in line 2 is referring to the salary you declared in class B, and your main method is part of class B so main can see any private stuff of B.
Every class has access to its private members. And "salary" is in class, along with your main method. That's why main method can access "salary".
Line 2 is the same as doing this:
B bObject = new B();
System.out.println(b.salary);
You can access the private variable because "bObject" is of type B. Now what you couldn't do is:
A aObject = new A();
aObject.bSalary;//if you changed the name of the salary variable to bSalary

Categories

Resources