I need to modify an argument to a function in Java. How do I add the argument to the callers using automation?
For example, In class A a method hello(int a ) exists. Now I am adding String to the same function argument so it becomes hello(String b , int a). If class B calls this method,how do I update the calling line in class B.
A a = new A();
int a; String b;
a.hello(a) % change to a.hello(b,a); //Assuming b is accessible.%
Eclipse provides this functionality via refactoring. Do they expose this API to external world or any other API is there?
You can right-click onto the method, select Refactor and select Change Method Signature. This opens a dialog that allows you to add new parameters, change parameter order, etc. When adding a new parameter you can provide a "Default Value" that will be used as argument in all classes that are currently calling the changed method.
Only classes with source that are currently in open Projects of the current Workspace are changed. The "outside world" will not get any notification of that. If you want to keep things runnable you should follow the advice to create a second method with the additional parameter and keep the old one (calling the new one with fitting default value). This can also automatically be done by mentioned refactor-dialog by checking the checkbox "keep original method as delegate to changed method".
Instead of trying to find all calling instances of a method, I would overload the method to include a way to handle passing in a string.
Class A(int a){}
Class A(String a){}
when you call these methods with the appropriate argument, you call that specific method. If you already have method calls using String a as an argument, a)you should get compiler errors, but more importantly b)this would fix all of them.
You can overload the method to add more parameters. All you have to do is define another method with the same name that takes different arguments.
public class A{
public void hello(int a){
//do things
}
public void hello(String b, int a){
//do things
}
}
The JVM will determine which method to use based on the given arguments during run time. If this isn't the functionality you need just give me a heads up.
Related
What are the advantages/disadvantages of init method over a constructor in java? They both have the same purpose. How to choose between them?
public class A {
private int x;
public A(int x){
this.x = x;
}
public void init(int x){
this.x = x;
}
}
Here we can use either constructor or init method.
You are wrong. They do not have the same purpose.
A constructor is always required when you want to create a new object using the new() operator.
A init method is something that might make sense in certain contexts, for example servlet stuff (see here for further reading regarding this aspect).
And please note: in your example, one could your init method more as a setter - as it is simply setting the corresponding field.
Coming from there:
first of all, you think about the constructors that you want to put into you class (by asking: which information is required to create a new instance of the class)
if there is special need, then consider adding setters for specific fields - or as layed out above, it might be required to provide an init() method (in case where object creation and initializiation can not happen at the same point of time)
Constructor is not a regular method. It's special in a sense that it gets always called when you invoke new A(). If you don't provide a constructor, Java creates one automatically. As a consequence, constructors do not have a return (i.e. they return this) and always have the same name as the class.
On the other hand, init is a regular method, which you can call - or not. There is no universally accepted consensus for any kind of "init" methods. So it depends on what you want to do. If you want to ensure that the new calls your logic, use constructor. If you want to have your own stuff, use plain methods. You can mix and match, just be sure to write a good documentation about how your class is supposed to be used.
This question already has answers here:
Function with same name but different signature in derived class not found
(2 answers)
overloaded functions are hidden in derived class
(2 answers)
Closed 8 years ago.
I learned something new about C++ the other day; the following does not work:
class ParentClass {
public:
void someFunction() { printf("ParentClass::someFunction()"); }
};
class ChildClass : public ParentClass {
public:
void someFunction(int a) { printf("ChildClass::someFunction(int)"); }
};
int main() {
ChildClass childClass;
// This call is a compiler error.
// I would expect it to call ParentClass::someFunction()
childClass.someFunction();
}
However, doing exactly the same thing in Java (among other languages) works just as I would expect:
public class ParentClass {
public void someFunction() { System.out.println("ParentClass"); }
}
public class ChildClass extends ParentClass {
public void someFunction(int a) { System.out.println("ChildClass"); }
}
public class Main {
public static void main(String[] args) {
ChildClass childClass = new ChildClass();
// The following prints "ParentClass"
childClass.someFunction();
}
}
So what gives in C++? Why does this hide the name instead of overloading it?
If you're asking what the rules are, then name lookup stops as soon as it finds one or more overloads within one scope, and doesn't look at any wider scopes. So, in your case, the search for someFunction starts in the scope of ChildClass, finds a match, and stops.
Only the name is considered, not its usage (e.g. number of arguments in a function call), accessibility, or anything else. If none of the overloads are usable, the search still doesn't continue to other scopes, and the program is ill-formed.
If you're asking why the rules are like that, consider the case where, initially, there's just one function:
struct Base {};
struct Derived : Base {void f(int);}
and someone calls it with a type that doesn't quite match
Derived d;
d.f(42.0); // OK: double converts to int
Now suppose someone, who knows nothing about Derived, decides that Base could do with another function:
struct Base {
void f(double); // Completely unrelated to D::f
};
Under the C++ rules, that function will be ignored by the code using D::f, which will continue to work as before. If the new function were considered as an overload, it would be a better match, and the code using D::f would suddenly change behaviour, potentially leading to much head-scratching and lengthy debugging sessions.
If you want to include all the base-class functions in the scope of the derived class to be considered as overloads, then a using-declaration will do that. In your case:
using ParentClass::someFunction;
Alternatively, to avoid the situation described above at the cost of some tedious verbiage, you could write forwarding function(s) for the specific overload(s) you want:
void someFunction() {ParentClass::someFunction();}
In C++, name hiding can take place when one function in base class has the same name as one function in derived class. The reason is phases of the function call process.
In C++, phases of the function call process are as following
Name lookup
Overload resolution
Access control
Name lookup stops looking for other names as soon as it finds a name in derived class ChildClass. Therefore, ChildClass::someFunction() hides any function with name someFunction in ParentClass.
After the name lookup process, overload resolution fails since there is no someFunction() in ChildClass.
The core difference is that in C++ the method signature is essentially just the method name whereas in Java it is the method name and its parameters.
In your case, by using the same method name you are overriding the parent method so the parent method taking no parameters is not available any more. In Java you must override with a method that both has the same name and has the same parameters to override a method so in your case they are both still available.
There is a completely different debate about whether the return type should also be included - let's not go there.
I'm having some troubles with overriding a base class in java 1.7.
My goal is to override the method f(), so that the program will iterate using a different function than the one in the base class.
My problem is that I can't seem to override the function, even though they're named the same, have the same return type, and the same parameters.
Here's the base file
And here's the file that's trying to override the base file
Currently the code works, I can set all the initial and ending values, I just can't get the function method in the second file to override the first.
You can't override a static function.
This is not overriding (an instance method), this is hiding (a static method).
As mentioned, static method can't be overridden. Consider making methods non static and using object instance to do calculations.
Something like this will go to Runge5.
public static void main(String argv[]) {
Runge2 r = new Runge5();
r.doCalculations();
}
doCalculations() would include the code that you had in main();
It's, probably not the best design but it will solve your problem.
I have recently found out that no argument constructor and multiple argument constructor cannnot call each other in turns. What is the underlying reason of this limitation? Some might say that constructors are where resources are initialised. So they must not be called recursively. I want to know if this is the only reason or not. Functions/methods/procedures can be called recursively. Why not constructors?
The answer lies in the fact that the call to another constructor is the first line of any constructor and hence your if condition to break out of recursion will never be executed and hence stack overflow.
The main purpose of the constructor is to initialize all the global variables described in a particular class.
For Example:
public class Addition(){
int value1;
int value2;
public Addition(){ // default constructor
a=10;
b=10;
}
public Addition(int a, int b){
this(); // constructors having parameters , overloaded constructor
value1=a;
value2=b;
}
}
public class Main(){
public static void main(){
Addition addition = new Addition(); //or
Addition addition = new Addition(15,15);
}
}
Here, if you want to make instance of the class you can either make instance by calling default constructor or by calling constructor having parameters. So the constructors are overloaded and not overridden. If you want to call another constructor, that can only be done be putting either this() or super() in the first line of the constructor. But this is not prefferable.
Constructors are not intended to be called explicitly outside object initialization, because it's restricted in most (I guess all) languages. Instead, you can create an additional protected Init(...) member function and call it inside the constructor.
Your statement that constructor cannot call other constructors are not true for every programming languages. At least I know Java can do this, while C++ cannot. But you could easily overcome this limitation by writing a private __init function and let all your constructors call it.
In all languages you've listed objects contain finite (and normally short) set of properties. Each property could contain recursive structure (i.e. list), but it still represented by a single property in the object.
I don't see need to recursively call constructors. It feels like a strange use recursion to initialize several well know properties.
As you've said you can call constructors in non-recursive way to share code in some languages you've mentioned.
C#: Using Constructors
public Employee(int weeklySalary, int numberOfWeeks)
: this(weeklySalary * numberOfWeeks)
{
}
Consider
Class A has two constructors new A(int), new A(int, String)
also
it has a method show()
Then given a statement like,
A a1= new A(4);
A a2= new A(3, "foo");
and later in code (or in some methods where these object were passed)
a1.show();
a2.show();
new A(3).show();
and
new A(2,"bar").show();
If I wanted to differentiate between these show methods based on the objects (a1 and a2) as well as based on class instance expression (calling show directly on constructors) and did not know which constructor was used (especially for the objects a1 and a2) how do I find that out--say reflectively?
The only way to do this would be to have each constructor set a different variable to indicate that it was used.
But I agree with Tom; this sounds like a bad idea. It shouldn't matter how you created an object (because a constructor may not even have been used at all, say, in serialisation), it should only matter that all it's properties (public or not) are set appropriately, to reflect the state it needs to be in.
Maybe A should be two different classes (each with a different constructor); or two different subclasses of a common base class: in that way, each class could have it's own distinct implementation of the show method.
Alternatively, have a data member inside A (perhaps a boolean, or the string) whose value is set differently by each constructor.
If two classes have different sets of behavior then they are two distinct classes. A single class should not behave differently based on how it was constructed.
Agree that you're better off using two separate classes, in which case you could use polymorphism (example in C#),
public class Base
{
public BaseClass()
public virtual void Show
{
// show stuff
}
}
public class A : Base
{
public A(int i)
public override void Show()
{
// show A stuff
}
}
public class B : Base
{
public B(int i, String s)
public override void Show()
{
// show B stuff
}
}
Then call the classes
Base a1= new A(4);
Base a2= new B(3, "foo");
and it should be easy to differentiate between these show methods based on the a1 and a2 objects.
It is not possible to determine by reflection which constructor was used to instantiate an object. Why not simply set an instance variable to a different value in each constructor to track which one was called?
So all four ways of calling show should perform a difference action?
Why and what is the difference between each of the actions?
Without knowing more we can only make wild guesses. It does sound like a job for two or maybe even four classes (plus an base class/interface) and a factory to create them.
If the question is purely theoretical - No, you can not tell at run time the difference between:
A a = new A();
a.show();
and
new A().show();
The only way to do so would be to exam the sourceĀ¹, so you would have to include the source and compile with full source numbers included. The parse the source code to work out how it was called.