Call a method in another class within 3 classes in java - java

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();

Related

Objects of multiple class in java

I was revising some of the old school concepts of Java in order to solve one problem . I have written the following code where i am trying the create objects of multiple class in that same classes and calling the methods with those objects from the main.
class a {
public void display() {
System.out.println("inside class a");
a a1= new a();
}
}
class b {
public void display() {
System.out.println("inside class b");
b b1= new b();
}
}
public class one {
void display() {
System.out.println("inside class one");
}
public static void main(String[] args) {
one o = new one();
a1.display();
b1.display();
o.display();
}
}
I am getting object cannot be resolved error. My question is what i need to change to let the above code work. And, do i need to always declare objects inside the main().
Any help will be highly appreciated
I'm not really sure why you would want to do that, but assuming you're just wondering about the possibility to implement such a thing - yes, it can be done.
You can create an instance of a class inside that same class, like so:
public class A {
public static A instance = new A();
public void display() {
System.out.println("inside class A");
}
}
Pay attention to the static modifier in the above code; it allows you now to access instance from another place (class, method, main) like so:
A.instance.display();
If you want to know whether you can declare a variable inside a method, and not a class, and make it accessible from another method, then the answer is - no, you cannot.
Yes you need to declare objects inside the main()
class a {
public void display() {
System.out.println("inside class a");
}
}
class b {
public void display() {
System.out.println("inside class b");
}
}
public class one {
void display() {
System.out.println("inside class one");
}
public static void main(String[] args) {
a a1= new a();
b b1= new b();
one o = new one();
a1.display();
b1.display();
o.display();
}
}
Don't know what you want to achieve and yes you should create object of class a and class b inside main functions to use instance methods of these classes.
package com.stack.overflow;
class a
{
public void display()
{
System.out.println("inside class a");
//a a1= new a(); ---> No need of this line as you can
// directly access instance variables and methods directly without
// creating any object or you can also use **this** keyword for the same
}
}
class b
{
public void display()
{
System.out.println("inside class b");
//b b1= new b(); ---> No need of this line as you can
// directly access instance variables and methods directly without
// creating any object or you can also use **this** keyword for the same
}
}
public class one
{
void display()
{
System.out.println("inside class one");
}
public static void main(String[] args) {
one o = new one();
a a1=new a();
b b1=new b();
a1.display();
b1.display();
o.display();
}
}
You may find the answer to your confusion easily - #ratul-sharker : a1 & b1 must be declared and instantiated inside the main. as well as other answers here correcting your code.
The real question is your notion of scoping and lifetime of variables - Not only a1 and b1 lie inside the classes a and b but they have been instantiated inside methods so they are local. So, try to understand the difference between field variables and local variables - their lifetimes and scopes are vastly different.
Accessing a local variable directly like that(which will be instantiated when the method is called) is like asking asking for a result from future in the present. Note that field variables will remain as long as object is alive but the local variables will remain only for the duration of the method call.
Hope it is clear to you now.
Also, your question:
My question was is it possible to create an object of an class in the
same class and call it from main?
Yes. Because main is a static method so it is not bound to an object like non-static method does. static methods are class level while non-static methods are object level. You can also create an instance in a non-static method for that matter.

When does the constructor initiallize?

I wrote down this mini-program:
A class:
public class A
{
public A()
{
System.out.println(getS());
}
public String getS() { return s;}
}
B class:
public class B extends A
{
private String s = "hello2";
public String getS() { return s;}
}
main:
public static void main(String[] args)
{
B b = new B();
}
and it printed:
null
Why is that?
I know that the String that printed is B's string, but why it didn't initialized before?
According to this answer - the variable initialized before the constructor..
EDIT -
I edited the code so the unrelated code won't confuse
Here is what's going on: when you construct B, the first thing its constructor needs to do is constructing A. This is done before B's own field s is initialized.
A constructs its own s, and then calls getS. However, it does not get its own getS, because B provides an override for it. Recall that B.s has not been initialized yet. That is why you see null printed.
Follow-up reading: What's wrong with overridable method calls in constructors?
What is happening:
You create a B instance, this will call the super() so the constructor of A.
Here it will do the print using the getter getS(). This will use the getter of B since this is the type of this but in this getter, the String is not yet instanciate since it is still doing the super class construction, so it return null.
Note that the String s in A is hidden by the one in B
The order during an instance is :
the static (from the super then the class)
the super class declaration (statement then constructor)
the block statement
the constructor
As Seen with :
public class A{
static{System.out.println("sA");}
{System.out.println("A1");}
public Main() {
System.out.println("new A");
}
{System.out.println("A2");}
public static void main(String[] args) {
new A();
}
}
class B extends Main {
static{System.out.println("sB");}
{ System.out.println("B1"); }
public B() {
System.out.println("new B");
}
{ System.out.println("B2"); }
}
Output :
sA
sB
A1
A2
new A
B1
B2
new B
it prints null because you have polymorphism in java. You Overrided method getS(). So when you call it from A, you try to call getS() from class B. But you didn't create instance of class B yet, because you need to finish class A first. So String in class B haven't been initialized yet, because of it you get null.

Calling method in object from object within it

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.

I expired some trouble with understanding Java polimorphism

public class XXX {
#Test
public void test() {
B b = new B();
b.doY();
}
}
class A {
public void doY() {
XProcedure.doX(this);
}
}
class B extends A {
public void doY() {
super.doY();
XProcedure.doX(this);
}
}
class XProcedure {
public static void doX(A a) {
System.out.println("AAAA!");
}
public static void doX(B b) {
System.out.println("BBBB!");
}
}
The output is
AAAA!
BBBB!
And I wonder why?
Although XProcedure has two methods with the same name - doX, the two signatures are different. The first method gets an instance of class A as a parameter, and the second one gets an instance of class B.
When you call XProcedure.doX(this), the correct method is called according to the class of the passed parameter.
"AAAA!" is printed because of the super.doY() call.
"BBBB!" is printed because of the XProcedure.doX(this); call.
this differs in A's constructor from this in B's constructor for the reasons in Che's answer. Although A's contructor is called from within a B's constructor, in A's scope, the instance is of class A.
You called super.doY which is a method on B's superclass A.
All animals can talk.
A cat is an animal.
A cat talks and drinks milk.

Calling An Inherited Class Method From Java

In Python, class methods can be inherited. e.g.
>>> class A:
... #classmethod
... def main(cls):
... return cls()
...
>>> class B(A): pass
...
>>> b=B.main()
>>> b
<__main__.B instance at 0x00A6FA58>
How would you do the equivalent in Java? I currently have:
public class A{
public void show(){
System.out.println("A");
}
public void run(){
show();
}
public static void main( String[] arg ) {
new A().run();
}
}
public class B extends A{
#Override
public void show(){
System.out.println("B");
}
}
I'd like to call B.main() and have it print "B", but clearly it will print "A" instead, since "new A()" is hardcoded.
How would you change "new A()" so that it's parameterized to use the class it's in when called, and not the hard-coded class A?
Static methods in java are not classmethods they are staticmethods. In general it is not possible to know which class reference the static method was called from.
Your class B does not have a main method and static methods are not inherited.
The only way I can see this happening is to find whatever is calling A.main( String[] arg ) and change it to call B.main instead.
B.main:
public static void main( String[] arg ) {
new B().run();
}
How is your program started? Is there a batch file, shortcut, etc? Something you can change? Where does A.main get called?
I think this isn't possible. Here's why:
In Java, the implementation of a method is determined by the instance's run-time type. So, to execute B.show(), you need to have an instance of B. The only way I could see to do this, if the method that constructs the instance is supposed to be inherited, is to use Class.newInstance() to construct an instance of a type that's not known at runtime.
The problem with that is that within a static method, you have no reference to the containing class, so you don't know whose newInstance method to call.
Why do you want to do this, though? There may be some better way to achieve whatever it is you want to achieve.
In your example I wouldn't put your main method inside of A. This is setup as the entry point into the system (you can't be in B if you are specifically entering into A).
In the example below I created class A, B, and C. Class C instantiates A and B and runs them. Notice that in C I created an A, a B, and another A that I instantiate as a B. My output is:
A
B
B
Hopefully this makes sense.
public class A {
public void show(){
System.out.println("A");
}
public void run(){
show();
}
}
public class B extends A {
#Override
public void show(){
System.out.println("B");
}
}
public class C {
public static void main(String[] args) {
A a = new A();
B b = new B();
A anothera = new B();
a.show();
b.show();
anothera.show();
}
}

Categories