how to reference an instance created in another class - java

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).

Related

Is a class that creates an instance of another its parent?

If class A creates an instance of class B, then in class B can I run a method from class A? sorry if the question is poorly worded, I don't know how else I could say it.
In the below code, Class A creates an instance of Class B and you can call Class A's method from Class B's method.
class A {
public void getA() {
System.out.println("In A");
}
public static void main(String[] args) {
B b = new B();
b.getB();
}
}
class B {
public void getB() {
System.out.println("In B");
A a = new A();
a.getA();
}
}
Output:
In B
In A
In class B you can call methods of class A only if A's methods are visible to B. It doesn't matter who created an instance of B.
This tutorial might help: http://www.tutorialspoint.com/java/java_access_modifiers.htm
So you can call it if the method is one of the following:
public
protected (and B is a subclass of A or B is in the same package as A)
no modifier (and B is in the same package as A)

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

Enforcing interface implementation in order to use another class

SITUATION: Say there is a class A and an interface B.
REQUIREMENT: If any class, say C, wants to create objects of A and use them, then that class will also have to implement interface B.Is there any way to enforce this condition?
WHY: Now a question may arise as to why I want to do such a thing. The reason is that when a class C creates objects of A and uses them, then those objects call certain methods of C. I want to declare those methods in interface B, so that C will invariably implement those methods.
Try this snippet:
public interface B {
// methods
}
public class A {
private final B b;
public A(B b) {
this.b = b;
}
...
}
public class C implements B{
// implement B's methods
public static void main(String[] arg) {
C c = new C();
A a = new A(c);
}
}
Since you say that objects of class A will call methods on C, they will have to keep reference to C somehow. Make this reference of type B and you are done.
That is
public class A {
public A(B arg) {
....
}
}
Then in C:
A a = new A(this);
That will force class C to implement interface B.

related to abstract class reference holding object of its derived class

class A is abstract and class B extends class A
now class A reference can hold object of class B,that is
A aObj = new B();
and assume class B has some extra methods....
like
class A
{
public show();
}
class B extends A
{
public show(){}
public method1(){}
private method2(){}
}
now tell me what things variable aObj can access from class B
can it access everything?
aObj only sees the public show() method. If you cast aObj to B, you can then access public method1(). public method2() is only accessible to the implementation of B.
For reference and completeness, here's a list of the possibilities:
A aObj = new B();
aObj.show(); // Works
aObj.method1(); // Error
aObj.method2(); // Error
And with casting to B:
B bObj = (B)aObj; bObj
bObj.show(); // Works
bObj.method1(); // Works
bObj.method2(); // Works inside bObj, but error otherwise
aObj can only use show() as the compiler thinks aObj is of type A, and the only known method of A is show().
If you know that you actually have a B you can cast that object to a B:
if (aObj instanceof B.class) {
B bObj = (B) aObj;
bObj.method1(); //OK
} else {
log.debug("This is an A, but not a B");
}
aObj.show();

Validating instances of inner-classes

I have a Java class B with an inner class C. Some methods of B accept an instance of C as parameter but I only want to accept C instances created by the proper instance of B. Is there a way to do this validation at compile time?
Example
C c1 = new C();
B foo = c1.getB(); // foo was created by instance c1
C c2 = new C();
c2.method(foo); // I want a compiler error here.
My case
Have a class names Map which hold a matrix of instances of the inner class MapArea. The nice thing about this scheme is that I can validate the xPos, and yPos fields at the constructor so no invalid Areas for a given map are built. The map as a method distanceFrom(MapArea startingPos, MapArea toLocation, MapArea... otherLocations) and I was trying to avoid to validate the map area arguments again.
If this is really the behavior you want, method() should really be defined in the inner class.
In other words, instead of:
public class C {
//...
public void method(B b) {
this.x = b.y;
//...
}
//...
public class B {
//...
}
//...
}
It should be:
public class C {
//...
public class B {
//...
public void method() {
C c = this.C;
c.x = this.y;
//...
}
//...
}
//...
}
Of course, this wouldn't solve the problem if, for example, you wanted public void method(B b1, B b2, B b3), where all three instances of B are enclosed by the same instance of C.
A compile error won't work, but you can at least throw an exception:
public class C
{
public static void main (String [] args)
{
C c1 = new C();
B b = c1.getB();
c1.useB(b); //OK
C c2 = new C();
c2.useB(b); //throws IllegalArgumentException
}
public B getB() { return new B(); }
public void useB(B b) {
if(b.getC() != this)
throw new IllegalArgumentException();
//...
}
private class B
{
public C getC() { return C.this; }
//...
}
}
There's no way (AFAIK) of doing this at compile time.
At runtime you can do it by having the outer instance's factory method pass a reference to itself to the inner instance's constructor.
The inner class would need to store that reference, such that the outer class can check whether it created that instance or not:
public class C {
public class B {
private C parent;
private B(C parent) {
this.parent = parent;
}
public C getParent() {
return parent;
}
}
public B getB() {
return new B(this);
}
public void method(B b) {
assert(this == b.getParent());
}
}
Actually, as Kip's concurrent answer shows, B can access C.this to get the parent object so there's no need to store the parent reference. However the method above would be necessary if C wasn't actually an inner class.
If you make the constructor of the inner class (C) private, I believe the enclosing class (B) can still instantiate it while other classes cannot. This ensures that only B and C can instantiate C.
Edit: I've verified that with a small mockup. Make the inner class constructor private, and then only the inner class (C) or the enclosing class (B) can instantiate it.
See http://tns-www.lcs.mit.edu/manuals/java-1.1.1/guide/innerclasses/spec/innerclasses.doc6.html for more. In particular: "Access protection never prevents a class from using any member of another class, as long as one encloses the other, or they are enclosed by a third class.".
There's no compile-time way to guard against instance-specific usage. Your best bet is probably throwing an Exception when the usage in incorrect. Another option you have is to have the parent class to have a Map of instances of the inner class, and to have other classes tell the outer class to operate on the inner class not by the instance but by some other references. This will work with other classes don't need to do anything directly with the inner class.

Categories