When Should You Use Get Methods vs Call Variables Directly? [duplicate] - java

This question already has answers here:
Why use getters and setters/accessors?
(37 answers)
Closed 4 years ago.
ok so i just found out that if you have a class with global variables you can call it in another class just by saying class.variable and now i'm very confused as to why getVariable and setVariable methods exist ever when they're already accessible
so let's say we have these two classes
public class MyClass {
public int num;
public String str;
public MyClass (int num, String str) {
this.num = num;
this.str = str;
}
public int getNum () {
return num;
}
public String getStr () {
return str;
}
}
public class test {
public static void main (String[] args) {
MyClass x = new MyClass (3, "string");
System.out.println(x.num);
System.out.println(x.str);
System.out.println(x.getNum());
System.out.println(x.getStr());
x.num = 4;
System.out.println(x.num);
}
}
Both ways, it accesses the same data from the object and outputs the same thing. Is one way better practice than the other or are there certain cases where one of the ways won't work?

Short answer: encapsulation.
A major benefit is to prevent other classes or modules, especially ones you don't write, from abusing the fields of the class you created.
Say for example you can an instance variable int which gets used as the denominator in one of your class methods. You know when you write your code to never assign this variable a value of 0, and you might even do some checking in the constructor. The problem is that some else might instantiate your class and later assign the instance variable a value of 0, thereby throwing an exception when they later invoke the method that uses this variable as a denominator (you cannot divide by 0).
Using a setter, you write code that guarantees the value of this variable will never be 0.
Another advantage is if you want to make instance variables read only after instantiating the class then you can make the variables private and define only getter methods and no setters.

Related

What is the proper way of calling a function of a same class without using objects in java? [duplicate]

This question already has answers here:
"Non-static method cannot be referenced from a static context" error
(4 answers)
Closed 3 years ago.
How do I call a function of the same class in java without using an object?
I tried this but got an error:
'non-static method facti(int) cannot be referenced from a static context'
System.out.print(facti(number));
public class Facto {
int i, fact =1;
int facti(int num){
if(num == 0){
System.out.print("For Zero ");
return 1;
}
else
for (i = 1; i <= num; ++i)
{
fact = fact * i;
}
return fact;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number for factorial : ");
int number = sc.nextInt();
Facto f1 = new Facto();
System.out.println(f1.facti(number));
}
}
Simple answer: you can't.
Your main method is 'static' it only can call other static methods (in the same class) or methods of an object. So you either can make "facti" static, too. Or you create an object: Facto f = new Facto(); f.facti(13); and call facti on that object.
Methods in Java are bound to objects unless specified otherwise. For example, consider the function foo(String str) in the class Bar:
public class Bar {
public void foo(String str) {
doSomething(this);
System.out.println(str);
}
}
This method is "attached" to a particular instance of the class Bar, meaning that it is effectively passed in as another parameter (e.g. like foo(String str, Bar this)). In Java, this is a reserved keyword, and refers tho this "hidden parameter".
Since this method has this hidden parameter, you must call it on an instance of Bar, for example:
Bar bar = new Bar();
bar.foo("hello");
If you just call: Bar.foo(), the "hidden parameter" does not know what it should be, and so this fails at compile time.
If, however, you do not need to refer to a particular instance during your method, you can mark it as static. This means you can call it on a class, rather than a type, like Bar.foo();
The error you are receiveing (non static method cannot be refernenced from a static context) is saying:
you are trying to call a non-static method facti(int i) (or, with a "hidden parameter", facti(int i, Facto facto)).
The context (i.e. the method you called it from: public static void main(String[] args)) is a static method, and so does not have this hidden parameter.
To fix it, either:
Make your method static, to avoid the need for a particular instance of Facto
Create an instance using new Facto(), and call it on that: e.g. new Facto().facti(123);

How to define a method with Integer parameter (path placeholding)?

Preface
I'd like to saying two things:
I don't know how to phrase this question in a few words. So I can't find what I'm looking for when searching (on stackoverflow). Essentially, I apologize if this is a duplicate.
I've only been programming Java consistently for a month or so. So I apologize if I asked an obvious question.
Question
I would like to have a method with a parameter that holds (path to) an integer.
How is such a method implemented in Java code?
Restrictions
The parameter should be generic.
So, when there are multiple of that integer variables, the correct one can be used as argument to the method, when it is called (at runtime).
My Idea as Pseudo-Code
Here's the idea of what I want (in pseudo-code). The idea basically consist of 3 parts:
the method with parameter
the variables holding integer values
the calls of the method with concrete values
(A) Method
.
Following is the definition of my method named hey with generic parameter named pathToAnyInteger of type genericPathToInt:
class main {
method hey(genericPathToInt pathToAnyInteger) {
System.out.println(pathToAnyInteger);
}
}
(B) Multiple Integer Variables
Following are the multiple integer variables (e.g. A and B; each holding an integer):
class A {
myInt = 2;
}
class B {
myInt = 8;
}
(C) Method-calls at runtime
Following is my main-method that gets executed when the program runs. So at runtime the (1) previously defined method hey is called using (2) each of the variables that are holding the different integer values:
class declare {
main() {
hey("hey " + A.myInt);
hey("hey " + B.myInt);
}
}
Expected output
//output
hey 2
hey 8
Personal Remark
Again, sorry if this is a duplicate, and sorry if this is a stupid question. If you need further clarification, I'd be willing to help. Any help is appreciated. And hey, if you're going to be unkind (mostly insults, but implied tone too) in your answer, don't answer, even if you have the solution. Your help isn't wanted. Thanks! :)
Java (since Java 8) contains elements of functional programing which allows for something similiar to what you are looking for. Your hey method could look like this:
void hey(Supplier<Integer> integerSupplier) {
System.out.printl("Hey" + integerSupplier.get());
}
This method declares a parameter that can be "a method call that will return an Integer".
You can call this method and pass it a so called lambda expression, like this:
hey(() -> myObject.getInt());
Or, in some cases, you can use a so called method referrence like :
Hey(myObject::getInt)
In this case both would mean "call the hey method and when it needs an integer, call getInt to retrieve it". The lambda expression would also allow you to reference a field directly, but having fields exposed is considered a bad practise.
If i understood your question correctly, you need to use inheritance to achive what you are looking for.
let's start with creating a hierarchy:
class SuperInteger {
int val;
//additional attributes that you would need.
public SuperInteger(int val) {
this.val = val;
}
public void printValue() {
System.out.println("The Value is :"+this.value);
}
}
class SubIntA extends SuperInteger {
//this inherits "val" and you can add additional unique attributes/behavior to it
public SubIntA(int val) {
super(val);
}
#override
public void printValue() {
System.out.println("A Value is :"+this.value);
}
}
class SubIntB extends SuperInteger {
//this inherits "val" and you can add additional unique attributes/behavior to it
public SubIntB(int val) {
super(val);
}
#override
public void printValue() {
System.out.println("B Value is :"+this.value);
}
}
Now you method Signature can be accepting and parameter of type SuperInteger and while calling the method, you can be passing SubIntA/SuperInteger/SubIntB because Java Implicitly Upcasts for you.
so:
public void testMethod(SuperInteger abc) {
a.val = 3;
a.printValue();
}
can be called from main using:
public static void main(String args[]){
testMethod(new SubIntA(0));
testMethod(new SubIntB(1));
testMethod(new SuperInteger(2));
}
getting an Output like:
A Value is :3
B Value is :3
The Value is :3
Integers in Java are primitive types, which are passed by value. So you don't really pass the "path" to the integer, you pass the actual value. Objects, on the other hand, are passed by reference.
Your pseudo-code would work in Java with a few modifications. The code assumes all classes are in the same package, otherwise you would need to make everything public (or another access modifier depending on the use case).
// First letter of a class name should be uppercase
class MainClass {
// the method takes one parameter of type integer, who we will call inputInteger
// (method-scoped only)
static void hey(int inputInteger) {
System.out.println("hey " + inputInteger);
}
}
class A {
// instance variable
int myInt = 2;
}
class B {
// instance variable
int myInt = 8;
}
class Declare {
public static void main() {
// Instantiate instances of A and B classes
A aObject = new A();
B bObject = new B();
// call the static method
MainClass.hey(aObject.myInt);
MainClass.hey(bObject.myInt);
}
}
//output
hey 2
hey 8
This code first defines the class MainClass, which contains your method hey. I made the method static in order to be able to just call it as MainClass.hey(). If it was not static, you would need to instantiate a MainClass object in the Declare class and then call the method on that object. For example:
...
MainClass mainClassObject = new MainClass();
mainClassObject.hey(aObject.myInt);
...

How do I get some variable from another class in Java? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am "playing around" with Java, watching tutorials and trying to get the hang of it. For this question, I'm trying to figure out how I can take a variable from another class and use it in my main one, without making the initial variable public. Here is the code:
I am trying to get int x equal to 5 (as seen in the setNum() method), but when it prints it gives me 0.
Main Class:
package getVarTest;
public class Main {
public static void main (String[]args){
Vars varsObject = new Vars();
int x = varsObject.getNum();
System.out.println(x);
}
}
Variable Class:
package getVarTest;
public class Vars {
private int num;
public void setNum(int x){
this.num = 5;
}
public int getNum(){
return num;
}
}
So, as you can see I am trying to take the private int num and make the int x in the main class equal to it.
I am trying to get int x equal to 5 (as seen in the setNum() method) but when it prints it gives me 0.
To run the code in setNum you have to call it. If you don't call it, the default value is 0.
You never call varsObject.setNum();
Do NOT do that! setNum(num);//fix- until someone fixes your setter. Your getter should not call your setter with the uninitialized value ofnum(e.g.0`).
I suggest making a few small changes -
public static class Vars {
private int num = 5; // Default to 5.
public void setNum(int x) {
this.num = x; // actually "set" the value.
}
public int getNum() {
return num;
}
}
If the variable is public you can get it just by saying packageName.ClassName.variableName, but if it is private you will have to make a getter method inside the class that the variable is in. It will look something like this:
public int getVariableName() {
return variableName;
}
Then just call that method wherever you need it.
Your example is perfect: the field is private and it has a getter. This is the normal way to access a field.
If you need a direct access to an object field, use reflection. Using reflection to get a field's value is a hack and should be used in extreme cases such as using a library whose code you cannot change.
The code that you have is correct. To get a variable from another class you need to create an instance of the class if the variable is not static, and just call the explicit method to get access to that variable. If you put get and set method like the above is the same of declaring that variable public.
Put the method setNum private and inside the getNum assign the value that you want, you will have "get" access to the variable in that case

how to declare a helper method in java, to be used locally being able to reference variables

I have a class with several methods. Now I would like to define a helper method that should be only visible to method A, like good old "sub-functions" .
public class MyClass {
public methodA() {
int visibleVariable=10;
int result;
//here somehow declare the helperMethod which can access the visibleVariable and just
//adds the passed in parameter
result = helperMethod(1);
result = helperMethod(2);
}
}
The helperMethod is only used by MethodA and should access MethodA's declared variables - avoiding passing in explicitly many parameters which are already declared within methodA.
Is that possible?
EDIT:
The helper mehod is just used to avoid repeating some 20 lines of code which differ in only 1 place. And this 1 place could easily be parameterized while all the other variables in methodA remain unchanged in these 2 cases
Well you could declare a local class and put the method in there:
public class Test {
public static void main(String[] args) {
final int x = 10;
class Local {
int addToX(int value) {
return x + value;
}
}
Local local = new Local();
int result1 = local.addToX(1);
int result2 = local.addToX(2);
System.out.println(result1);
System.out.println(result2);
}
}
But that would be a very unusual code. Usually this suggests that you need to take a step back and look at your design again. Do you actually have a different type that you should be creating?
(If another type (or interface) already provided the right signature, you could use an anonymous inner class instead. That wouldn't be much better...)
Given the variables you declare at the top of your method can be marked as final (meaning they don't change after being initialized) You can define your helper method inside a helper class like below. All the variables at the top could be passed via the constructor.
public class HelperClass() {
private final int value1;
private final int value2;
public HelperClass(int value1, int value2) {
this.value1 = value1;
this.value2 = value2;
}
public int helperMethod(int valuex) {
int result = -1;
// do calculation
return result;
}
}
you can create an instance of HelperClass and use it inside the method
It is not possible. It is also not good design. Violating the rules of variable scope is a sure-fire way to make your code buggy, unreadable and unreliable. If you really have so many related variables, consider putting them into their own class and giving a method to that class.
If what you mean is more akin to a lambda expression, then no, this is not possible in Java at this time (but hopefully in Java 8).
No, it is not possible.
I would advise you create a private method in your class that does the work. As you are author of the code, you are in control of which other methods access the private method. Moreover, private methods will not be accessible from the outside.
In my experience, methods should not declare a load of variables. If they do, there is a good chance that your design is flawed. Think about constants and if you couldn't declare some of those as private final variables in your class. Alternatively, thinking OO, you could be missing an object to carry those variables and offer you some functionality related to the processing of those variables.
methodA() is not a method, it's missing a return type.
You can't access variables declared in a method from another method directly.
You either has to pass them as arguments or declare methodA in its own class together with the helpermethods.
This is probably the best way to do it:
public class MyClass {
public void methodA() {
int visibleVariable=10;
int result;
result = helperMethod(1, visibleVariable);
result = helperMethod(2, visibleVariable);
}
public int helperMethod(int index, int visibleVariable) {
// do something with visibleVariable
return 0;
}
}

When making a class to hold variables should the variables always be static?

Say I wanted to make a class to hold a set of integers that would be accessed from multiple other classes and instances. I don't want them reverting to the value they had when the code was compiled. Does that mean they have to be static, in order to keep them from going back their original value? For example
The original stats holding class here:
public class Stats() {
public static int numOne = 0;
public static int numTwo = 5;
public static int numThree = 3
//etc...
}
It is called on in two places. Here:
public class exampleClass() {
private Stats stats = new Stats();
stats.numOne += 5;
//More variable changes.
}
Also here:
public class exampleClassTwo() {
private Stats stats = new Stats();
stats.numOne -= 3;
//More variable changes.
}
Will these calls reset the variables to their original class value if the variables are not static? If so, does that mean they should always be static?
No, the variables will maintain state without the static modifier
No. You would use static key word for using those values without initializating them.
public class Stats() {
public static int numOne = 0;
public static int numTwo = 5;
public static int numThree = 3
//etc...
}
public class exampleClass() {
int a = 0;
a += Stats.numThree;
System.out.println(a);
}
>>> 3;
No need for static attributes in your case indeed, each class instance will contain a private copy of attributes initialized at instance creation time, and records all subsequent modifications until object is deleted (in java it means no longer referenced).
Main usage for static is either to store constants or global state (e.g. a singleton instance).
Doing,
private Stats stats = new Stats();
stats.numOne += 5;
Kind of defeats the purpose of having numOne as static.
The static field numOne should be accessed in a static way i.e as follows: Stats.numOne
static variables are Class variables and are used when we want to maintain a value across instances of the class. So modifying the value of numOne across various functions will keep on changing the value of class variable numOne. Run the following code to see the effect of having a class variable in a class:
public class StaticVarDemo {
public static int staticCount =0 ;
public StaticVarDemo(){
staticCount++;
}
public static void main(String[] args) {
new StaticVarDemo();
StaticVarDemo.staticCount +=5;
System.out.println("staticCount : " + StaticVarDemo.staticCount);
new StaticVarDemo();
new StaticVarDemo();
System.out.println("staticCount : "+staticCount);
}
}
It will give the output:
staticCount : 6
staticCount : 8
Yes, when you instantiate an object, variables will be initialized to the class values when they are not static.
When a variable has the static keyword, that variable value persists over all instances: the two places you called it each create an object, both objects have the same values for their static variables (even if they are changed).
Variables without the static keyword are unique to the instance: changing it on one object doesn't affect its value on the other.
See here for more info:
What does the 'static' keyword do in a class?
It seems after some research a singleton did the job. Creating one singular instance but calling on it more then once.
See Here:
http://www.tutorialspoint.com/java/java_using_singleton.htm

Categories