Passing an object by reference in Java - java

Okay, so I have the following code.
Main class
public class Main {
public static void main(String[] args) {
Integer val = 20;
User user = new User(val);
System.out.println(user.getVar());
val = 21;
System.out.println(user.getVar());
}
}
User class
public class User {
private Integer var;
public Integer getVar() {
return var;
}
public void setVar(Integer var) {
this.var = var;
}
public User(Integer var) {
this.var = var;
}
}
The thing I struggle to understand is why the value in User class doesn't change when we change its reference in Main class. How can we change a value in User class changing the reference of the object anyway? I clearly don't understand something crucial about passing an object by reference and I'll be really glad if someone clarifies this moment for me.

Related

Variable access in another class

I have a variable in x class .And I have another class called "Y" to access the variable. Will it change the value in X class, if the value is incremented in Y class?
Java uses pass by value but we can achieve what you are asking for by passing an object as an argument to a method like this:
public class ClassX {
public int classId;
public ClassX(int id) {
this.classId = id;
}
public void setId(int id) {
classId = id;
}
public int getId() {
return classId;
}
}
public class ClassY {
public static void main(String[] args) {
ClassX cx = new ClassX(100);
ClassY cy = new ClassY();
System.out.println("classId:"+cx.classId);
cy.modifyId(cx); // an object is passed as argument to a method
System.out.println("classId:"+cx.classId);
}
public void modifyId(ClassX classx) {
classx.setId(220);
}
}
Assuming you have it defined like
public int anInteger = 4;
Then yes, it would change.
These are the sorts of things best learned from experimentation, try various ways of structuring the classes, declaring the variable, and accessing it. See what happens.
Yes. All you need is to pass a reference to it to the other class.

What's the correct way to "share" variables between methods in different classes?

I'm trying to share variables between methods in different classes, but I don't know if I'm doing this in the correct way. Basically when I wanna use the variables on method2 I have to "transport" them throught method1 to method2 from the Class A, just take a look at the example because I don't know how to explain this properly.
Is this the correct way to do it? Because sometimes I do this over an over through methods and it looks ugly.
Example:
public class A {
int var1, var2, var3;
B b = new B();
b.method1(var1, var2, var3);
}
public class B {
public void method1(int var1, int var2, int var3){
//doSomething
method2(var2, var3);
}
public void method2(int var2, int var3){
//doSomething
}
}
Btw, is there any community where code reviews are done? I'm pretty new to code and I'm afraid that I'm creating code that isn't effective.
Thanks for the help! :)
Use getters and setters to get variable of Class A from B as following..
public class A {
private int var1, var2, var3;
public int getVar1(){
return var1;
}
public void setVar1(int var1){
this.var1 = var1;
}
public int getVar2(){
return var2;
}
public void setVar2(int var2){
this.var2 = var2;
}
public int getVar3(){
return var3;
}
public void setVar3(int var3){
this.var3 = var3;
}
}
public class B{
// Use var 1 from class A as following
A a = new A();
int x = a.getVar1(); //x has the value of Var1 now
a.setVar1(2); // var1 in class A has value 2 now.
}
Use interfaces rather than directly call a method of another class.
public class A {
private InterfaceB interfaceB;
interfaceB.method1(var1, var2, var3);
}
public interface InterfaceB{
public void method1(int var1, int var2, int var3);
public void method2(int var2, int var3);
}
public class B implements InterfaceB{
#Override
public void method1(int var1, int var2, int var3){
//doSomething
method2(var2, var3);
}
#Override
public void method2(int var2, int var3){
//doSomething
}
}
You should read about encapsulation.
Passing 3 variables encapsulated in 1 object with appriopriate accessors sounds like a better option to me (at least the code looks a bit cleaner).
Also, think of creating a utility class with static methods if it makes sense of course - sometimes you do not need class member fields at all because there is no state to this class (Math class is an example) and static methods that return the result of some calculation/transformation is a better option.
On a side note I can recommend you considering "Program to an interfaces" principle. You can read the relevant section right on the top of this page.
In B class, you declare a instance of A class, variables in A class is public. when you can use variable in A class.
Here is my 2 cents...
public class Sample {
//Property of the class
private int valueA;
//method to do some operation
//that relies explicitly on a
//property of the class
public void doSomething(){
//valueA is over 9000!?
int valueA = valueA + 9000;
}
//Method that does something that does not explicitly
//rely on a property of the class
//could be called from this or another class
public int doSomeOperationWithSomething(int something){
return something++;
}
}
Another alternative would be to create a static "utility" class for your methods
public class Utils{
public static int doMagic(int var){
return var * var;
}
}
used like this,
int num = Utils.doMagic(9);
These come about when you have some code that does that one useful thing, but you just can't figure out where to put it.
More importantly, you will want to maintain proper "encapsulation" (Read about that) in your code. This means limiting access to variables by other classes and allowing access to only what is needed.
public class Website {
//No one should ever be able to
//access this variable directly
//So we set it a private
private String article;
//A reader should be able to get the aricle
public String getArticle(){
return article;
}
//The reader should never be able to set
//an aticle on the website only read it
//You can leave this part out or
//set the method to private as i did.
private void setArticle(String article){
this.article = article;
}
}
public class Reader {
//Reference to website
private Website website;
public Reader(){
...
//the user can read an article
website.getArticle();
// but this is not available to them
website.setArticle("Some text"); // results in ERROR
}
}

How to override the base class method without creating object for base class if you know anyone can you give the example?

I also done this example creating object for both class and call the method is there anyway to override the baseclass?
class Car {
void Max() {
System.out.println("Audi");
}
}
class Speed extends Car {
void Max() {
System.out.println("300");
}
public static void main(String args[]) {
Speed s=new Speed();
s.Max();
}
}
At the risk of being called a "give me the repz" type person...hopefully this helps:
This first class is a BaseClass, you can create a new one by writing:
BaseClass myBaseClass = new BaseClass();
public class BaseClass {
private int aNumber; //This global variable is private and so cannot be overwritten.
int anotherNumber; //This global variable is package scope and so can be accessed by sub-classes in the same package.
protected yetAnotherNumber; //This variable is accessible by any subclasses.
public int numberAvailableToEveryone; //This global variable is accessible to anyone and everyone.
public BaseClass() {} //This is a constructor (no return type)
private void myPrivateMethod() {} //This method cannot be overwritten
void packageScopeMethod() {}
protected void thisMethodCanBeOverwrittenBySubClasses() {}
public void theWorldCanCallMe() {} //extendable to the world, not much different than protected scope tbh
}
Now, to overwrite a method you can create an anonymous class like so:
BaseClass myAnonymousClass = new BaseClass() {
public void theWorldCanCallMe() {
//in here you can override the method to do whatever you want.
}
}
or you could define a subclass like so:
public class SubClass extends BaseClass {
#Override
public void tehWorldCanCallMe() {
//again your new code goes here
}
}
and then instantiate it like so:
SubClass myClassThatOverridesAMethod = new SubClass();
A car example closer to your code:
class Car {
private String name;
int speed = 100;
Car(String name) { //This is the base classes constructor
this.name = name;
}
String max() {
return speed;
}
void run() {
System.out.println(name);
System.out.println(max()); //will print the base speed unless overridden
}
}
class Audi extends Car {
Audi() {
super("Audi")
}
}
class Speed extends Car {
Speed() {
super("Speed");
}
#Override
String max() {
speed = 300;
return speed;
}
public static void main(String args[]) {
Speed s=new Speed();
s.run();
}
}

Java Passing variables around classes

I am new to java and am trying to pass variables like in the following example from one class to another, im wondering is this possible and how i would go about it if it is.
As this code does not work as it is not static.
Main Class
public class testAll
{
public static void main(String[] args)
{
One one = new One();
Two two = new Two();
}
}
The first class:
public class One
{
public int test = 4;
public int getTest()
{
return this.test;
}
}
The second class:
public class Two
{
public void value()
{
System.out.print("Var is: " + One.getTest());
}
}
Thanks,
Naz
Lets consider this, if you want to access a variable in Class A from Class B then Class A needs to know about Class B.
public class A {
public A(B classB){
this.classB = classB;
}
public void printValue(){
System.out.println(this.classB.getTest());
}
}
Now you will need to pass an instance of ClassB to ClassA in the constructor so that Class A has a reference to ClassB when it calls printValue();
ClassB b = new ClassB();
ClassA a = new ClassA(b);
b.getTest();
a.printValue();
You have to create an instance for class One first. Try this
public void value()
{
One one_object = new One();
System.out.print("Var is: " + one_object.getTest());
}
public class Two {
private One one;
public Two(One one) {
this.one = one;
}
public void printValue() {
System.out.print("Var is: " + one.getTest());
}
}
public class Main {
public static void main(String [] args) {
One one = new One();
Two two = new Two(one);
two.printValue();
}
}
There are two way - pass a reference or pass a value:
public class One {
private int value = 0;
public One(final int value) {
this.value = value;
}
public int getValue() { return value; }
}
public class Two {
private One one = null;
public Two(final int value) {
this.one = new One(value);
}
public Two(final One one) {
this.one = one;
}
public int getValue() { return one.getValue(); }
}
When passing a reference to a One instance, the value is read from One and will only change it the value held inside the One instance changes. When passing a primitive (int, boolean ...) the value is copied and "owned" by the Two instance. Read some more about the differences of references and values to grasp the idea. It's quite simple, once you get the idea.

Inheritance in Java

Consider the following code in Python:
class A(object):
CLASS_ATTRIBUTE = 42
def f(self):
return "CLASS_ATTRIBUTE: %d" % self.CLASS_ATTRIBUTE
class B(A):
CLASS_ATTRIBUTE = 44
Now A().f() and B().f() return "CLASS_ATTRIBUTE: 42" and "CLASS_ATTRIBUTE: 44" respectively.
How can I achieve a similar effect in Java? I want a CLASS_ATTRIBUTE field to be initialized statically and redefined in the inherited class but the f method should be only defined in the base class.
Is there a particular reason you want the attribute to be static? In Java the typical way you'd do this is to have A contain a protected variable that you then set in the constructors of the 2 classes:
public class A
{
protected int CLASS_ATTRIBUTE;
public A()
{
CLASS_ATTRIBUTE = 42;
}
public String f()
{
return "CLASS_ATTRIBUTE: " + CLASS_ATTRIBUTE;
}
}
public class B extends A
{
public B()
{
CLASS_ATTRIBUTE = 44;
}
}
Alternatively (and probably more consistent with Java design patterns) you'd declare a function that you can override to return the value instead of using a member variable.
Short answer: you cant solve it like this in Java. You'll have to solve it in another way.
In Java you can't override or "redeclare" fields in subclasses, and you can't override static methods.
It can be solved using an ugly reflection-hack (should be avoided though):
public class Main {
public static void main(String... args) {
A a = new A();
B b = new B();
System.out.println(a.f()); // Prints 42.
System.out.println(a.fReflection()); // Prints 42.
System.out.println(b.f()); // Prints 42.
System.out.println(b.fReflection()); // Prints 44.
}
}
class A {
static int CLASS_ATTRIBUTE = 42;
public int f() {
return CLASS_ATTRIBUTE;
}
public int fReflection() {
try {
return getClass().getDeclaredField("CLASS_ATTRIBUTE").getInt(null);
} catch (Exception wontHappen) {
return -1;
}
}
}
class B extends A {
// Compiles, but will not "override" A.CLASS_ATTRIBUTE.
static int CLASS_ATTRIBUTE = 44;
}
You can't do this directly with only a variable, because in Java variables cannot override (they only shadow the super classes variables).
You need to use a protected "getter" method, which can then be overridden by the subclass:
class A
{
private int attribute=42;
...
protected int getAttribute() {
return attribute;
}
}
class B
extends A
{
private int attribute=44;
...
protected int getAttribute() {
return attribute;
}
}
But note there's a special consideration to calling methods from an object's constructor, in that it allows object code to run before object construction is complete.
I'm not sure if you meant "statically" literally or not, but here's a brief example of how inheritance at it's most basic form looks in Java. Note that using a getter method to access the variable is a better idea for several reasons -- this is just an example.
public class Dog {
protected String whatISay = "Woof!";
public void speak(){
System.out.println(whatISay);
}
}
public class Poodle extends Dog {
public Poodle(){
whatISay = "Yap!";
}
}
public class Main {
public static void main(String[] args){
Poodle fluffy = new Poodle();
fluffy.speak();
Dog dog = new Dog();
dog.speak();
}
}
Yap!
Woof!
This way of doing it introduces as little intrusion as I could think of. setAttribute() could be named something like setDefaultValue() if that's clearer.
public class A
{
protected int attribute;
public A()
{
setAttribute();
}
public String f()
{
return "CLASS_ATTRIBUTE: " + attribute;
}
protected void setAttribute()
{
attribute = 42;
}
}
public class B extends A
{
#Override
protected void setAttribute()
{
attribute = 44;
}
}
public class Main
{
public static void main(String[] args)
{
A a = new A();
B b = new B();
System.out.println("A: " + a.f());
System.out.println("B: " + b.f());
}
}

Categories

Resources