In Java, I have something like this
public class A {
private String title;
public A () {
// do something
}
public void run () {
B b = new B();
b.run();
}
public void changeTitle(String newTitle) {
this.title = newTitle;
}
}
public class B {
public B() {
// do something
}
public void run() {
}
}
My question is in method run() of B, is it possible to invoke method changeTitle() in A to change the title of the instance of A that instantiates B?
Thanks
B can only invoke methods on A if it contains a reference to an instance of A. You could pass an instance of A into B to achieve this.
public void run () {
B b = new B(this);
b.run();
}
public class B {
private A a;
public B(A a) {
this.a = a;
a.changeTitle("Ha!");
}
}
if B accepts a type A in its constructor, and when you say new B, pass in 'this' similar to
public void run () {
B b = new B(this);
b.run();
}
now you have a copy of the A object your working with.
Sure. Pass an instance of A in the constructor for B.
This will only be possible if you pass this as argument when you invoke B's run() method.
Not unless you arrange for instances of B to know what instance of A they should do that to (e.g., by passing that into the constructor for B and remembering it).
If you're doing something like this then you should consider, e.g., what you want to happen if an instance of B is created by something other than an instance of A.
no. As such an instance of B does not know who created it.
However with B as:
public class B {
private A creator;
public B(A creator) {
this.creator = creator;
// do something
...
}
and creating new B(this) in A.run(), B could call creator.changeTitle("whatever") in its run() method.
Is B is a non static inner class of A you van invoke the mehods of A (and access its fieldes).
Related
I have a class A and within class A I have function func1 and func2.
In the same file I have class B and in that class B I have function func3.
In the main class, an object obj1 of class A is declared.
With this object, func1 of class A is called.
Within func1 of class A, an object obj2 of class B is created.
With this object, func3 of class B is called.
Now within func3 of class B, i want call func2 of class A with the object obj1. For this I want to refer to that object from within func3 of class B. Is it possible? If yes, how?
I tried using this.this.func2 which wouldn't work.
For now I am passing the object obj1 as an argument and it works fine. But I want to do the same without passing it because I want to use an array of objects and every time the object should differ
class A {
int attr1, attr2;
public void func1() {
int attr1 = 3;
int attr2 = 6;
B obj2 = new B();
obj2.func3();
}
public void func2() {
this.attr1 = 5;
this.attr2 = 10;
}
}
class B {
int atr1, atr2;
public void func3() {
atr1 = 4;
atr2 = 8;
// here I want to access the object obj1 to call the function func2()
}
}
public class Main {
public static void main(String args[]) {
A obj1 = new A();
A.func1();
}
}
Is it possible?
Yes.
If yes, how?
Option 1: Pass as parameter
Pass obj1 as parameter to func3.
Or more precisely, since func3 is called from a method of obj1, pass this as the parameter value:
class A {
public void func1()
{
B obj2 = new B();
obj2.func3(this);
}
}
class B {
public void func3(A a)
{
a.func2();
}
}
Option 2: Pass to constructor
Pass the A reference to the B constructor, and have B remember it in a field.
class A {
public void func1()
{
B obj2 = new B(this);
obj2.func3();
}
}
class B {
A a;
public B(A a) {
this.a = a;
}
public void func3()
{
this.a.func2();
}
}
Option 3: Inner class
Make class B an inner class of A. Essentially the same as option 2, but the compiler handles the reference to A for you.
class A {
public void func1()
{
B obj2 = new B();
obj2.func3();
}
class B {
public void func3()
{
A.this.func2();
}
}
}
What I mean by this is, if I have A obj1 = new B(); A obj2 = new B(); I want to know how to call the same method for both objects, and also want to know how to know which object is calling the method and when:
For example, lets say my class hierarchy looks something like this:
abstract class A {
public void method_1() {
//Do something
}
}
class B extends A {
public boolean method_2(A obj) {
//Do something
}
}
If I where to do obj1.method_2(obj2); How do I, inside method_2(), when I code it so both obj1 and obj2 call method_1(), distinguish which obj is calling the method?
I hope my question was clear enough.
I'm sorry in advance if my English wasn't understandable enough.
obj1 which is instance of B but references class A, won't have access to method_2
So you need to cast like this
((B) obj1).method_2(obj2);
or you can change the reference to B instead of A
B obj1 = new B();
Base reference can't call the child's method.
public class Main {
public static void main(String arg[] ) {
A obj1 = new A() {};
A obj2 = new B();
B obj3 = new B();
obj1.method_1("1 "+obj1.getClass());
obj2.method_1("2 "+obj2.getClass());
obj3.method_1("3 "+obj3.getClass());
obj3.method_2(obj1);
obj3.method_2(obj2);
}
}
abstract class A {
public void method_1(String className) {//Do something
System.out.println("A.method_1() called by "+className);
}
}
class B extends A {
public boolean method_2(A obj) {//Do something
super.method_1("4 "+obj.getClass());
obj.method_1("5 "+obj.getClass());
return true;
}
}
You can NOT create an object of class A as its abstract class. However you can create object of B and pass it in place of A in method_2(). When you call method_1() inside method_2(), you are still calling it through object of class B. Here is the test program I could write based on my understanding of your question -
public class App {
public static void main(String[] args) {
B b = new B();
B b2 = new B();
b.method_2(b2); //Or
//b.method_2((A)b2);
}
}
abstract class A {
public void method_1() {
System.out.println("In method_1 = " + this.getClass());
}
}
class B extends A {
public boolean method_2(A a) {
System.out.println("In method_2 = " + this.getClass());
a.method_1();
return false;
}
}
The result is that both methods are called by object of class B. You can user getSuperClass() method to get superclass name.
If we have 2 classes like this :
public class A {
public static int m=10;
public int b(){ m++; return m;}
public int fun() {
return b();
}
}
public class Testfun() extends A {
#Override
public int b() {return 1;}
public void test(){
A a = new A();
assertEquals(1,a.fun());
}
}
Is there any way to make the method fun() in class A call the overriden b() instead of the its super b()?
The idea is:
I suppose to test the method fun() and do a stub b(). So I don't want the method to call the original b() and call the stub one.
Is there any way to make the method fun() in class A call the overriden b() instead of the its super b() ?
No way. The instance you have is of type A and methods from A gets called. Period.
No you can not call.The instance you have is of type A and methods from A gets called.
No, it's not possible, because object don't know how many of it's childs or are there any of it. When you want to test something inside a class and want to stub it it's signal of you need to make it dependency of the class like this:
public class A {
private final B b;
public A(B b) {
this.b = b;
}
public int fun() {
return b.b();
}
}
public interface B {
int b();
}
public class Testfun() {
public void test(){
B b = new B {
public int b() {
return 1;
}
};
A a = new A(b);
assertEquals(1, a.fun());
}
}
In this example we make B as dependency of class A and able to change B from desirable implementation in runtime to test dummy in testing. When you need to test B itself you need separate class that tests B. See https://en.wikipedia.org/wiki/Strategy_pattern
Thanks for all, it really helped me !
My mistake was here
A a = new A();
It should be :
A a = new Testfun();
Therefor the overriden b() will be called.
I have class In java: A. And class B which extends class A.
Class A hold instance of class B.
I notice that when I call the constructor of class B (when I init this parameter in class A), It does super(), create a new instance of A and init all it fields.
How I can tell class B that the concrete instance of class A (which init it field) - it his parent class?
Your question is really hard to understand, but I guess the problem is this this (your approach):
public class A {
public B b = new B();
}
public class B extends A {
}
So, when you run new A() you get a StackOverflowError.
In my practical experience, I never needed a design like that, and I'd strongly recommend to re-think your approach. However, if it is really needed, you could use a dedicated init() method, e.g.:
public class A {
public B b;
public void init() {
b = new B();
}
}
A a = new A();
a.init();
If you needed A within B you could just do it with a custom constructor for B:
class B extends A {
A a;
public B() {
super();
this.a = this;
}
}
This case is harder though so you need:
class A {
B b;
}
class B extends A {
public B() {
super();
b = this;
}
}
Note that you should not pass the B into the call to super() as B will not be initialized, you should do it as the last step in the constructor of B.
I am trying to update a jlabel from another class. I've pasted my code below.
Class A {
public void setNetAmount(String s){
jLabel51.setText(s);
}
public void setDis_percentage(String s){
jLabel53.setText(s);
}
public void setDiscount(String s){
jLabel55.setText(s);
}
public void setAdjustment(String s){
jLabel57.setText(s);
}
}
Class B{
public void SetData(){
new A.setNetAmount(""+netAmount);
new A.setDis_percentage(""+dis_percentage);
new A.setDiscount(""+discount);
new A.setAdjustment(""+adjustment);
}
}
I am calling the SetData() method in Class A.
public void getData(){
B b = new b();
b.setData();
}
Is there anything wrong with my code ? It is not working at all. Is there any issue of EDT? Please help.
You can't keep invoking "new A". This creates a new instance of class A.
Not really sure why you have a class B to invoke a few methods from class A, but if you use this approach then you would need to pass a reference of class A the your class B method.
Something like:
public class B
{
public void setData(A a)
{
a.setAmount(...);
a.setPercentage(...);
...
}
}
Then when you invoke the method in your class A you would use:
B b = new B();
b.setData(this);
Although this is a really strange design.