I have the following problem, and no idea how to solve it. Let's say we have a class classA, and in this class is the main method creating an object of the class itself. Now we take another class, classB. In the constructor of classA we make an object of classB. Now in a method of classB we want to call a method of classA.
Let me provide you with an example.
public class classA {
public classA() {
//some code
classB objectB = new classB();
}
public static void main(String[] args) {
classA objectA = new classA();
//more code
}
public void methodA() {
//even more code
}
}
public class classB {
public void someListener() {
//code needed to call methodA of the object objectA
}
}
The question is: what would the code be, where there is now just the comment //code needed to call methodA of the object objectA?
The reason I'm in this situation, is that in the code that I'm going to use it for, there are various methods running in objectB controlled by loops, but once a certain thing happens a method in what is shown here as objectA has to be called. How do I do this?
Simple ... just pass the reference of class A object to object of class B. Let class B store the reference and call the methods of A whenever necessary.
New Code (commented)
public class classA{
classA{
//some code
classB objectB = new classB(this); //------------- pass reference here
}
public static void main(String[] args){
classA objectA = new classA();
//more code
}
public void methodA(){
//even more code
}
}
public class classB{
private classA storedReference = null; //------------- you need a variable of classA to store the reference
public classB(classA passedObject){ //------------- you need an appropriare constructor
storedReference = passedObject; //------------- store the classA object reference
}
public void someListener(){
storedReference.methodA(); //------------- call methods whenever necessary
//code needed to call methodA of the object objectA
}
}
You can pass a reference to ClassA to the constructor in ClassB e.g
class ClassB(ClassA ref) {
ref.someMethod();
}
However you need to be careful if you're calling a method on an instance of a class that you're constructing. The class may not have completed its construction and may be be in an incomplete state.
You need to add constructor to your classB, so that you can pass a classA as reference to it.
So your classB becomes:
public class classB {
classA cA;
public classB(classA cA) {
this.cA = cA;
}
public void someListener(){
cA.methodA();
}
}
And your classA constructor :
classA{
//some code
classB objectB = new classB(this);
}
In ClassB, you want to call a method of ClassA. That's not difficult to do, but I believe you have your relationships incorrect.
If you're using the current code you have: You need to pass an instance of ClassA to ClassB, which can be accomplished using the this operator:
public classA() {
//some code
classB objectB = new classB();
objectB.someListener(this);
}
In classB:
public void someListener(classA theClassA) {
//code needed to call methodA of the object objectA
theClassA.methodA();
}
If you want to reverse the relationships between the two: Instead of having an instance of classB in classA that relies on classA to do its work, have classB be the dominant object, and have it contain and instance of classA.
Related
Base class:
public class BaseClass
{
public void beforeClass
{
TestDataLoader loader = new TestDataLoader(); //some implementation here
readData = loader.fetchdata(...);
}
}
Class-1:
public class ClassA extends BaseClass
{
String a;
public void method1()
{
..
..
}
}
Class-2:
public class ClassB extends classA
{
String a1;
public void methodB(ClassA classA1)
{
if(classA1 == null)
{
//do nothing
}
classA1.method1();
}
}
The problem i see here is that i am not able use testDataLoader (for which the implementation is in BaseClass) of ClassA in my ClassB. I am able to access method1 of ClassA in my ClassB but i am not able to use the testDataLoader of ClassA in ClassB
Note: i cannot pass arguments to method1 of ClassA as it won't support arguments to be passed to it.
Could someone help me on this?
We have class library as
class A {
public void callWorkflow() {
B b = new B();
}
}
class B {
public void callStatic() {
C.someMethod();
}
}
class C {
public static someMethod() {}
}
We are actually trying to change functionality of static method someMethod. Is there a way to solve this problem without changing call hierarchy?
You can't just Override a static method. In my opinion, remove static from the method someMethod(), then create an object of class C inside class B. Then call the method.
Class A{
public void callWorkflow() {
B b = new B();}
}
Class B{
public void callStatic(){
C c = new C();
c.someMethod();}
}
Class C{
public someMethod(){}
}
There is no way to override a static method.
That's why one of these approaches is preferred to calling static methods:
Inject another object (service) that will provide the functionality in a non-static method and call it through the injected object
Make the static method a thin wrapper that just delegates the work to some non-static object that can be configured (like in slf4j's logger)
This is for a personal project. Not assignment or work.
Say I have an object, objA that has a function callB().
When I run callB() it calls a function in object B. The function in objB can have calls to functions in objA.
Eg. objA calls callB().
Inside callB() there is a function like setObjAName() which sets a variable on objA.
How would I do this in Java? How do I reference objA from objB?
The simplest method is to simply pass a reference to A in with the method call, which will allow for B to access any of A's public methods.
public class ClassA {
public String someAVar;
public void callB(ClassA a){
//do stuff
ClassB b = new ClassB();
b.setObjA(this,"newValue");
}
}
public class ClassB{
public void setObjA(ClassA A, String newValue){
A.someAVar = newValue;
}
}
Alternatively you might want the variable to be settable without passing in a particular instance, in which case static methods and variables are your friend.
public class ClassA {
public static String someAVar;
public void callB(){
//do stuff
ClassB b = new ClassB();
b.setObjA("newValue");
}
}
public class ClassB{
public void setObjA(String newValue){
ClassA.someAVar = newValue;
}
}
I've 3 classes in one package. The first class (ClassStart) generates each an instance of the 2 other classes (ClassA and ClassB). I want to call in ClassB a method of ClassA by means of its instance "a".
Though the scope of Instance "a" is the package (because of the attribute "ClassA a;" in ClassStart the line "a.showText()" doesn't work. It gets the error message "a cannot resolved".
So I tried "s.a.showText()" but it doesn't work because the instance "s" was generated in a static method and I don't know how to access to "s".
The first class (contains the main-method):
public class ClassStart {
ClassA a;
public static void main(String[] args) {
ClassStart s = new ClassStart();
}
public ClassStart() {
a = new ClassA();
ClassB b = new ClassB();
}
}
The second class:
public class ClassA {
public void showText() {
System.out.println("This text comes from ClassA.");
}
}
The third class:
public class ClassB {
public ClassB() {
a.showText();
}
}
How can I call in ClassB the method "showText()" of the ClassA?
(I had looked for answers in this forum but I didn't find a answers for a three class problem like this.) Thank you for answer.
If the ClassA object needs to be the same throughout, then pass it into B:
public class ClassB {
private ClassA a;
// pass the ClassA reference into the ClassB constructor
public ClassB(ClassA a) {
this.a = a; // assign it to the a field
// a.showText(); // or you can do this if you need it called in the constructor
}
// or do this if you want the a method called in a ClassB method.
public void callAShowText() {
a.showText();
}
}
then:
public class ClassStart {
ClassA a;
public static void main(String[] args) {
ClassStart s = new ClassStart();
}
public ClassStart() {
a = new ClassA(); // create your ClassA instance
ClassB b = new ClassB(a); // pass it into your ClassB instance
b.callAShowText();
}
}
The key bit of understanding here is to understand reference types and reference variables. You want a reference variable in ClassB to refer to the ClassA object created in ClassStart. One way to do that is to pass the object into ClassB either in its constructor or in a setter method. Once you've done that, then ClassB has the reference it needs and it can call any ClassA method on the instance.
Note that you can also "solve" this by creating and using a public static ClassA variable or a public static showText() method, but in general you will try to avoid doing this since while it would work fine in a simple example like this, it doesn't "scale" well, meaning if used generally in larger more complex programs, it will risk increasing the potential connections in your complex program, greatly increasing the risk of bugs. It was for this reason, to decrease complexity and decrease connectedness (decrease coupling) that object oriented programming was created.
Make the method static:
public static void showText()
Then call it:
ClassA.showText();
I am having a class 'ClassA' which is having private constructor.
public final class ClassA{
private ClassA{
}
public static void main(String[] arg) }{
;
;
;
}
}
Now, i am extending the class 'ClassA' [ final keyword is removed before doing this ]
public class ClassB extends ClassA{
public static void main(String[] arg) }{
;
;
;
}
}
Now, i am getting Implicit super constructor classA() is not visible. Must explicitly invoke another constructor. What does it mean and how to resolve this?
Note i can not change the access specifier of ClassA constructor.
Change the constructor visibility of ClassA from private to protected.
Constructors always begin by calling a superclass constructor. If the constructor explicitly contains a call to a superclass constructor, that constructor is used. Otherwise the parameterless constructor is implied. If the no-argument constructor does not exist or is not visible to the subclass, you get a compile-time error.
I would suggest composition instead of inheritance (maybe that's what the designer of ClassA intended for class usage. Example:
public class ClassB {
private ClassA classA;
ClassB() {
// init classA
...
}
public ClassA asClassA() {
return classA;
}
// other methods and members for ClassB extension
}
You can delegate methods from ClassB to ClassA or override them.
Java will implicitly create a constructor with no parameters for ClassB, which will call super(). In your case the constructor in ClassA is not visible, hence the error you are getting. Changing the visibility to public or protected will resolve the error.
Changing private ClassA{} to protected ClassA{} sounds like a good solution.
Parent constructor is always called in child class: implicitly or not. So, your ClassB definition is equivalent to
public ClassB extends ClassA {
public ClassB() {
super();
}
// all other methods you have go here...
}
If the only constructor of ClassA is private, it can't be called from ClassB.
Because the son must invoke father's constructor for Complete the initialization of the parent's parameters.
Now ClassA is final class and it's constructor is private.If ClassB extends ClassA.
remove final of the ClassA
invoke super() or super(**), change private to public/protected, or add constructor for ClassA
public class ClassA {
private ClassA() {
}
// add
protected ClassA(String str) {
}
public void display() {
System.out.println("Father's display");
}
}
class ClassB extends ClassA {
public ClassB() {
// add
super(null);
}
public void display() {
System.out.println("Son's display");
}
}