java reference to the outer object from inner object - java

JAVA
public class A {
string amountA;
B b;
}
public class B {
string amountB;
public void setValue(String value) {
amountB = value;
Also, I need to set amountA = value;. Is it possible? See main method
}
}
... main(String... args) {
A a = new A();
B b = a.getB(); // b is a member of A
b.setValue("25") // this should also change 'amountA' in object 'a' to '25'
}

If you need to set both valueA and ValueB to the same value, it makes more sense to have a setter in class A that would set both of them :
public void setValue(String value) {
amountA = value;
b.setValue(value);
}
You can't access an instance of A from within an instance of B, since B is not an inner class of A. You can create an instance of B that is not related at all to any instance of A.

public class A {
public class B {
string amountB;
public void setValue(String value) {
amountB = value;
amountA = value; // Using A.this.amountA
}
}
string amountA;
public B createB() {
return new B(); // Provides A.this to the B instance.
}
}
... main(String... args) {
A a = new A();
B b = a.createB(); // b is created inside A
b.setValue("25") // this should also change 'amountA' in object 'a' to '25'
}
You can use an inner class.
The class itself should better create the instance, so that A.this is set into the b.
Alternatively
B b = a.new B();
But I never ever used that.
Inner classes are practical for a container element having access to its container class.
Another solution is to make a method in A with the B object as parameter or so.

It sounds like you want to have A derive from B rather than contain an instance of B. That way the valueA in an instance of A and the valueA in the instance of B associated with that instance of A are really the same variable. You can also have data in A that isn't shared with B by declaring it in A. For example,
public class A extends B {
public String amountAonly; // a string in A that's not in B
public B getB() { return (B)this; } // typecast to treat A like B
}
public class B {
public String amountA; // a string that's in both A and B
public void setValue(String value) {
amountA = value;
}
}
...
main(String[] args) {
A a = new A();
B b = a.getB(); // b is the B associated with a
b.setValue("25"); // will also change 'amountA' in object 'a' to '25'
}

Related

Avoiding Dynamic Type Casting with Inheritance for Data Classes in Java

I have 3 Data Classes
#Data
class A
{
private int a;
}
#Data
class B extends A
{
private int b;
}
#Data
class C extends A
{
private int c;
}
Class B and C have some common fields between them which is kept in their parent class A.
Following is the tester class
class TesterClass
{
static String bOrC = "C"; // input from some decision
public static void main(String[] args) // assume this to be the client
{
A a;
if (bOrC.equals("B")) {
B b = new B();
b.setB(11);
a = b;
} else {
C c = new C();
c.setC(12);
a = c;
}
a.setA(10);
doSomething(bOrC, a);
}
// Below are the service methods
// only this method in the service exposed
public static void doSomething(String bOrC, A a) {
if (bOrC.equals("B")) {
doSomethingWithB(a);
} else if (bOrC.equals("C")) {
doSomethingWithC(a);
}
}
public static void doSomethingWithB(A a) {
B b = (B) a; // possible ClassCastException
System.out.println(b.getA());
System.out.println(b.getB());
}
public static void doSomethingWithC(A a) {
C c = (C) a; // possible ClassCastException
System.out.println(c.getA());
System.out.println(c.getC());
}
}
Now the problem I see with this is unsafe Dynamic Type Casting which can run into Class Cast Problems. One possible solution would be to create separate data objects and set the common fields (which are too many for my actual case) for both the objects separately in both classes B and C which would then look as follows:
public class TesterClass
{
static String bOrC = "C"; // input from some decision
public static void main(String[] args)
{
if (bOrC.equals("B")) {
B b = new B();
b.setA(10); // duplication
b.setB(11);
doSomethingWithB(b);
} else {
C c = new C();
c.setA(10); // duplication
c.setC(12);
doSomethingWithC(c);
}
}
public static void doSomethingWithB(B b) {
System.out.println(b.getA());
System.out.println(b.getB());
}
public static void doSomethingWithC(C c) {
System.out.println(c.getA());
System.out.println(c.getC());
}
}
I'm looking for a way to avoid this dynamic type casting but at the same time avoid having to duplicate the common variables. Can anyone suggest a solution?
Abstraction is one solution for the behavior you are explaining. Creating an abstract method doSomething(...) in class A and implementing it in child class B and C respectively. By doing this you don't need to have a static method and processing will be done bases on the instance of B or C objects itself.
#Data
class A
{
private int a;
public abstract void doSomething();
}
#Data
class B extends A
{
private int b;
public void doSomething(){
/*.... do something here
* here you can also access parent public methods and properties.
* as you have already annotated with #Data you will have access to getA() method, * hence you can also use parent properties.
*/
}
}
#Data
class C extends A
{
private int c;
public void doSomething(){
/*.... do something here
* here you can also access parent public methods and properties.
* as you have already annotated with #Data you will have access to
* getA() method, * hence you can also use parent properties.
*/
}
Now you can use it as below
public static void main(Strings[] args){
A a;
B b = new B();
b.setB(10);
b.doSomething();
C c = new C();
c.setC(30);
c.doSomething();
}

How to get value of getter in class C which was setted in Class A (which was declared in Class B)

I am having three classes Class A which set Value, class B where both getter and setters are created, Class B which get value (set in Class A)
Because I was creating new instances of Class B in Class A and Class C. I am not able to get value in class Cwhioch was set in Class A.
What I acknowlegeds is We need to pass the reference to Class C instance from class A to Class B.
But I dont know how to do so.
I tried with this code. I know the result it is not possible. I dont know how to do it.
public Class A {
int X = 9;
B b = new B();
b.setValue(X);
}
public Class B {
private float value = 0;
public float getValue() {
return value;
}
public void setValue(float value){
this.value = value;
}
}
public Class C {
B b = new B();
final float x = b.getValue();
}
I expect when I use getValue() method of class B in Class C. I am able to get the value putted in Class A by setValue() method
Whenever you create an object using the "new" keyword, remember that you are creating a new object and a new memory space is alloted to it.
Now in class C, when you create a new object of B, a new memory space is alloted to this instance b.
(This instance b does not point to the same memory location that b in class A points to)
Immediately after the object is created, you are calling b.getValue() which will only give you the default value of "value".
when I use getValue() method of class B in Class C. I am able to get
the value putted in Class A by setValue() method
In order to get the value set in A, you need to call getValue() of b --
the object b which is in class A
(and not the object b which is declared in class C)
So you need to access it using a.b.getValue() in class C.
you may do that by adding public static property inside a Class.
Static property are associated to the class directly. they can be called even without creating an instance of the class, ex: ClassName.propertyName.
public Class B {
public static float value = 0;
}
inside Class A you can set B float value like this :
public Class A {
B.value = 9;
}
and get the value :
public Class C {
final float x = B.value;
}
First of all the instance of class B in Class A and Class C are different.
You don't have any getter in A class to get the Class B field values
You can create a method in Class C and pass by reference of instance in Class A.
Hope this helps you..
You may do that in the following way:
public class A {
int X;
B b;
public A(int x, b b){
this.b = b;
this.b.setValue(X);
}
}
public class C {
B b;
public C(B b){
this.b = b;
}
public float getX(){
return b.getValue();
}
}
Now you pass the same reference of B class to both class A and C as shown below:
public static void main(String[] args){
B b = new B();
A a = new A(9,b);
C c = new C(b);
float x= c.getX();
}
Finally, I am able to solve my question thanks for your suggestions.
But I actually did it. I made my getter and setter static. Now I don't need to create reference again to get value.
My code
public Class A {
int X = 9;
B b = new B();
b.setValue(X);
}
public Class B {
private static float value = 0;
public static float getValue() {
return value;
}
public void setValue(float value){
B.value = value;
}
}
public Class C {
final float x = B.getValue();
}
Try this out!!
In the Constructor of ClassA, pass reference of ClassB and set the Value.
public class ClassA {
int X=9;
ClassB b;
public ClassA(ClassB b){
this.b = b;
this.b.setValue(X);
}}
Similarly, In constructor of ClassC, pass reference of ClassB and call the method getValue() to retrieve the value set by classA.
public class ClassC {
ClassB b;
public ClassC(ClassB b){
this.b = b;
}
public float getX(){
return b.getValue();
}}
Class B has the setter and getter function. In the main function, create an instance for ClassB and pass the same reference to ClassA and ClassC.
public class ClassB {
private float value = 0;
public float getValue() {
return value;
}
public void setValue(float value){
this.value = value;
}
public static void main(String[] args){
ClassB b = new ClassB();
ClassA a = new ClassA(b);
ClassC c = new ClassC(b);
float x= c.getX();
System.out.println(x);
}}

how to access an instance of a class from its instance variable

So I have this scenario
class A:
public class A {
B b = new B();
public void doSomething() {
// this does something
}
}
and class B:
public class B {
public B() {
// need to access A
}
}
The problem is that I need to access the instance of A from the A's instance variable B. How do I do that?
You may simply pass the instance of A to B:
class A {
B b;
A() {
b = new B(this);//<-- A's instance
}
}
class B {
A a;
B(A a) {
this.a = a;
}
}
If class Bneeds to access an existing instance of A then you must provide the B instance with a reference to the A instance.
class B {
private A a;
B(A a) {
this.a = a;
// do something with a
}
}
then
A a = new A();
B b = new B(a);
If you need access to the A only within the constructor then you don't need to store a local copy of the reference.
You must create new object from instance A
A aa = new A();
OR
public class B extends A {
public B() {
// need to access A
}
}
Inner Class seems like the best thing to do ,
public class A {
B b = new B();
private int tryToAccess;
public void doSomething() {
// this does something
}
public class B{
public B()
{
tryToAccess=5;
}
}//B ends
}//A ends
Note:This is just one way of going about it , here you can access A's private variables from class B

How java casting work, is it change the state of Object or create new Object?

I have a method dummy with A as class parameter, but i need to pass instance of subclasses B to that method. I know from:
Does Java casting introduce overhead? Why?
that downcasting in java have overhead. Most of my code deal with subclass B so i dont use downcasting for this purpose. Instead i use temporal instance variable cc for that purpose. But this is not make a change for object of subclass m. I need change in variable cc avaliable too for instance variable m. This is my code:
public class TestCast {
public TestCast() {
B m = new B(12, 3);
dummy(m);
A cc = m;
dummy(cc);
System.out.println(m.a);
System.out.println(cc.a);
}
public void dummy(A t) {
t.a = 22222;
}
public static void main(String[] args) {
new TestCast();
}
}
class A {
public int a = 0;
public A(int a) {
this.a = a;
}
}
class B extends A {
public int a;
public int b;
public B(int a, int b) {
super(a);
this.a = a;
this.b = b;
}
}
with output
12
22222
In your particular example, both the parent and child classes declared a field with name a. In this case, the child variable hides the parent variable.
Also, variables/fields are not polymorphic entities like methods. They are accessed by the static type of a reference.
In other words, the field access
A var = new A(10);
var.a; // returns 10
And the field access
A var = new B(1501, 10);
var.a; // also returns 10
but
A var = new B(1501, 10);
var.a; // returns 10
((B)var).a; // returns 1501
because you access a on a reference with static type B.
In your method
public void dummy(A t) {
t.a = 22222;
}
The static type of t is A so you will modify the value of the parent class variable.
Casting is telling the compiler that a reference variable is of specific Type at runtime
Because B is extending A you do not want to re-define the variable a
In answer to your comment, you code should be something like:
class B extends A {
public int b;
public B(int a, int b) {
super(a);
this.b = b;
}
}
IMO, your example code is not perfect implementation of inheritance. Inheritance enables you re-usability of code. In other words, you don't need to declare int a again in class B.
I need change in variable cc avaliable too for instance variable m:
However, if you want to change in variable cc as well, then declare variables a, b as private/protected in both A and B. And provide setters and getters in both classes.
And in class B call super.setA(a) like below.
class B extends A {
private int a;
private int b;
public B(int a, int b) {
super(a);
this.a = a;
this.b = b;
}
public setA(int a) {
super.setA(a);
this.a = a;
}
}

how to reference an instance created in another class

I have a function in Class A which I would like to change the value of a field in Class B.
Class C has my main() and creates a new instance of class B and Class A. Class A is from an API and one of their functions is a listener function. I would like for that listener function to be able to change the field of Class B, but when I write the code for the listener function, it doesn't recognize Class B's instance.
How do I reference that instance?
Example code:
public class A {
public void listenermethod(){
//can't reference Binstance <-------
}
}
public class B {
B.field = 1;
}
public class C {
A Ainstance = new A();
B Binstance = new B();
}
You should give A class a private B field, and then you can call the public methods from B on this field as needed. If you need to create both A and B instances in a separate class (C) you should give your A class a public void setB(B b) setter method.
A.java
class A {
private B b;
public void setB(B b) {
this.b = b;
}
public void listenerMethod() {
if (b != null) {
b.someBMethod();
}
}
}
C.java
public class C {
public static void main(String[] args) {
A a = new A();
B b = new B();
a.setB(b);
a.listenerMethod();
}
}
You have to be able to modify both class C and class A. Rewrite the class A method to
public void listenermethod(Binstance theB){
theB.something = "some_value";
}
Now when you call class A, pass in the Binstance. If you can't modify class A, then your task can't be done.
An instance by definition belongs to an object. Therefore, your class A must either have an object of class B as a member:
Class A{
private B instance_of_b;
}
now you can access B members like this:
instance_of_b.member
or the field belonging to class B could be static and then A could access it through the class.
B.member
Also make sure you know the meaning of accessor keywords (private,protected,[friendly],public).

Categories