This question already has answers here:
Why is method overloading and overriding needed in java? [duplicate]
(2 answers)
Closed 4 years ago.
I asked on SE how to make a function that accepts different kinds of variables. People have told me to "overload".
My question: how do I use overloading to make a function that will accept multiple data types (int bool string) as it's input?
Also, what are the advantages and disadvantages of overloading? Is it related to "overloading my computer"?
Overloading is a concept that doesn't hurt your computer but sometimes it makes your head hurt. Not really. Overloading is just writing multiple implementations of a method with the same name but different parameter types. It requires the programmer to write code like this. Notice the return types are the same.
public int SomeMethod(int someValue)
{ //one implementation for ints }
public int SomeMethod(String someValue)
{ //another implementation for strings}
Which method is invoked depends on on the argument type. The method invoked here is the one for integer arguments:
int result = SomeMethod(5);
Another way of doing this is using Generic Methods. This is a little advanced for the question asked, but it might be what you're looking for. The Oracle Java Documentation is a good place to start.
Try looking into generic types: https://docs.oracle.com/javase/tutorial/java/generics/boundedTypeParams.html
Overloading is a concept. It will not affect your computer or your code. It is simply the fact of declaring multiple methods in your class with the same name but different arguments.
For example:
private int doSomething(int anInteger) {
// do something with an integer
}
private int doSomething(float aFloat) {
// do something with a float
}
Doing this will allow you to use the same method name on different parameter types, but have different method implementation.
public void myFunction(String s){ ... }
public void myFunction(int i){ ... }
public void myFunction(bool b){ ... }
Really you should be able to google "java overloading" or something instead of posting on here for this. Googling is a top developer skill. Read the documentation, or your textbook or something.
Related
I have a plan to make a GUI as minimal as it gets. I have hit a brick wall where I cant find an answer or maybe some kind of workaround due to me being inexperienced in java.
I have searched quite a bit and only found ways to replace the last letter or number in a string but not in a method call
public static int question;
public static void main(String[] args) {
int questionNumber = Integer.parseInt(JOptionPane.showInputDialog("Enter project no."));
if (questionNumber>=7){
questionNumber=6;
}
else if(questionNumber<=3){
questionNumber=4;
}
question = questionNumber;
System.out.println(question);
System.out.println(questionNumber);
for(int i=4; i<=6;i++)
if(question==i){
Question4(); // want the number 4 to be the question variable
}
}
What I would expect is
for(int i=4; i<=6;i++)
if(question==i){
Question *the variable "question" here* ();
}
and have no idea if that is possible or how to get there.
Is it possible to reference different methods with one method call in
a for loop?
Yes. It depends upon what exactly you mean by different methods. Here are three general ways in which this can be achieved:
The Java enum facility allows developers to define constant-specific methods, which are different method bodies defined in each separate enum constant declaration. The actual method body that is invoked depends upon the actual enum constant upon which the method call is made (this is actually a specialization of the next bullet item).
Interfaces enable different method bodies to be defined in each separate implementation. In this way, the actual method body that is invoked depends on the instance of the actual implementation upon which the method call is made.
Another way to invoke different method bodies with "the same method call" is to perform method invocations using Java's Reflection Facility. Since Java is an Object-oriented development environment, a decision to use reflection should be made carefully. Reflection is (often much) slower, less readable, and clumsier than solutions that don't use it. Reflection also makes many errors which could be detected at compile-time detectable at run-time only.
In Java, the principle mechanisms of abstraction are classes and interfaces and, so, when thinking about a problem domain and resolving that into an object domain you should be thinking about how to design interfaces and classes that provide the most natural description possible.
You want to be able to invoke a method that corresponds to a particular question. A better way to approach this is not to abstract over it with the method call to a question, but to abstract over the questions themselves. Your project has questions, so this is a good clue that you should have a Question class.
Here is a skeletal solution to the problem that makes use of the Java enum facility (enums are a special kind of class). This solution is similar to the one suggested by Matthieu but it does not need reflection at all; instead it uses the first bullet item above and defines constant-specific methods (which is, itself, a specialization of the second bullet item above):
public enum Question {
QUESTION_1 {
#Override public String getText() {
return "This is the text for Question #1.";
}
},
QUESTION_2 {
#Override public String getText() {
return "This is the text for Question #2.";
}
},
:
:
QUESTION_N {
#Override public String getText() {
return "This is the text for the final question in the series.";
}
};
public abstract String getText();
}
This enum class defines one constant for each question in the series of questions (each of these constant declarations becomes an instance of the enum class Question at run-time). Each declaration defines a different method body for the method getText() which is overridden inside each enum constant.
The declaration public abstract... at the end of the enum informs the compiler that every enum constant must provide an implementation for the getText() method. If a developer adds a new question to the series but forgets to add a getText() method in it, the compiler will complain (this is a type of error that can be caught at compile-time with an object-based solution that could only be caught at run-time if reflection were used).
Here is a simple program to exercise your Question enum class. It simply prints out the name of each question constant followed by its question text:
public static void main(String[] args) {
for (Question question : Question.values()) { // here is the "one for loop"
String text = question.getText(); // here is the "one method call"
println(question.toString());
println(text);
}
}
No reflection is used. Instead, natural abstraction mechanisms of Java's type system are able to achieve the desired goal of invoking a separate method body for each question.
Using map in this situation is most easiest solution. You should learn how to use them and how they works but, this is more about design now. If you want pass some parameters into your method take a look on Consumer, BiConsumer or even Function class provided by java. Check this example how it could implementation looks with Runnable that takes no parameters.
Map<Integer, Runnable> map = new HashMap<>(); // creating Map variable
// registering questions
map.put(1, () -> {
System.out.println("Question #1");
});
int questionNumber = 0;// get option id
if (map.containsKey(questionNumber)) { // first check if question is registered
map.get(questionNumber).run(); // get runnable that is registered with exact questionNumber and run it
} else {
// print invalid question number
}
You can use reflection:
try {
Method m = MyClass.class.getDeclaredMethod("Question"+questionNum);
m.invoke(this);
} catch (NoSuchMethodException e) {
// Handle
}
But you should handle the exception properly, because it will most probably fail one day or another.
You can also use an enum to define each behavior and call the appropriate:
private static enum EnQuestion {
Question1 {
public void run(MyClass instance) {
// ...
}
},
Question2 {
...
},
...
QuestionN {
...
};
public void run(MyClass instance);
}
The enum has to be static so you can't access MyClass protected/private fields and methods.
Then call it:
EnQuestion.values()[numQuestion].run(this);
This question already has answers here:
Return multiple values from a Java method: why no n-tuple objects?
(7 answers)
Closed 8 years ago.
While working with Java Applications, I feel most of the times one question : Why Java doesn't support multiple return values of methods?
I know that people who designed Java, must have done thinking about this topic but I didn't get any answer or particular reason while thinking myself.
If all the values are of the same type, you can just return an array of them:
public String[] myMethod{} {}
If they are not, they you have multiple options:
The ugly one is to cast everything into an Object and return either:
public Object[] myMethod{} {}
or
public List<? extends Object> myMethod() {}
The problem with these implementations is you really don't know what's what in the object/list unless you look at the method implementation. So it can be a shortcut if you know noone else is going to use this.
There's cleaner but a bit more time consuming. But it's usually a good practice because carries more information:
Say you want to return two values, an int and a String. You need to design an object that represents those two (or more values):
public class MyResponse {
public String myString;
public int myInt;
}
And return an instance of MyResponse. Note that here I made the attributes public. There are multiple schools of thoughts around this. Some will prefer to make them private and add getter/setter methods. That's homework for you.
Conceptually Java method should acomplish only one action on data and return concrete result. If you could not decide what should return your method this is a cause of bad OOP design of the class.
If you just want to return a several objects (one type of objects) from method you should use collections or arrays as #mprivat said.
I'm learning Java but I believe that this question is not language-specific. Sorry if someone has already asked the question, I'm not sure how to phrase this in a search query.
Shortly after implementing a few generic methods for myself, I came to realize that: Since Generics allow you to use parameters of more types, some of the arguments that the user puts in might not have the functionality that you expect. A "hack" that I came up with is to restrict the parameter input type using an interface as an Upper Bound. For popular functionalities like compareTo(), this is fine as the interface Comparable is popular enough, but I find it awkward that I have to write a custom interface just to get my generics to work.
Here's some code to help make sense of my nonsense. Consider the following non-working code that attempts to count unique elements in a collection of generic datatype:
public static <T> int countUnique(Collection<T> c) {
int count = 0;
for(T t : c) {
count += (t.isUnique()) ? (1) : (0);
}
return count;
}
An obvious problem arises when the compiler complains that the objects t do not have (or rather, the compiler cannot determine that they have) the method isUnique(). My solution:
public interface unique {
public boolean isUnique();
}
public static <T extends unique> int countUnique(Collection<T> c) {
int count = 0;
for(T t : c) {
count += (t.isUnique()) ? (1) : (0);
}
return count;
}
Question is: Do I have to do this every time? Isn't it clunky? Is there a standard practice that I should instead be adopting?
This is the main principle of OOP. You're working with objects and objects have behaviors (methods).
Every method knows what objects it is working with. For example, your method compares 2 numbers. If you pass 1 number and 1 Array of Strings it won't be able to compare them.
You don't have to use interface as upperbound in your example.It can be your class and in case you have 2 classes that have similar behavior then you create an interface and change your method above to use that interface.
Also, by Java Code Conventions interface name should start from capital letter.
This question already has answers here:
Java Pass Method as Parameter
(17 answers)
Closed 8 years ago.
I'm trying to write a function, so I can pass a function as a parameter, such as
public class HashFunction {
private Function f;
public HashFunction(Function f) {
this.f=f;
}
public Integer hash(String s){
return f(s);
}
}
So I can write code like
new HashFunction(function(String s){ return s.charAt(0)+0; });
Like in javascript.
How can I do this?
Unlike many other modern languages, currently java doesn't syntactically support "floating chunks of code" (known as closures).
However, the concept may be achieved through the use of anonymous classes, which are "on the fly" implementation declarations that typically implement an interface, but can also extend a class.
Here's how you would code your example in java:
public interface Hasher {
int getHash(String s);
}
public class HashFunction {
private Hasher f;
public HashFunction(Hasher f) {
this.f=f;
}
public Integer hash(String s){
return f(s);
}
}
then to use:
new HashFunction(new Hasher() {
public int getHash(String s) {return s.charAt(0)+0;}
});
Passing functions as parameters is not possible in Java, unless they added it in a recent language change.
The Java pattern is to use so-called anonymous classes, which implement a member method which has the desired behavior.
For example, see:
http://docstore.mik.ua/orelly/java-ent/jnut/ch03_12.htm
or
How are Anonymous (inner) classes used in Java?
I think you can use interface, the same way like Comparable or Comparator interface, or use annotation to mark some functions, and then use reflection to invoke them
Please check this
I can only second the other answers. Basically, it is not possible to pass real references to functions, like in JavaScript or Haskell, where "everything is a function".
However, if you want to have a little bit of "functional"-style programming in your code, take a look at the "Functional Java" library at http://functionaljava.org/
Maybe taking a look at Scala also can be helpful, as it runs in the JVM and is a very mature, upcoming and modern programming language. In Scala, you can pass functions and it would interoperate with your existing Java code, too. (There are functions, functors, monads, list comprehensions, ...)
functions are called methods in java. And you can pass them!!!
But this is advanced java. Use java.lang.reflection.Method to pass a method.
But you will not happy with that technique.
I have a String which can either be of Double or Integer type or some other type. I first need to create a Double or Integer object and then send it over to a overloaded method. Here's my code so far;
public void doStuff1(object obj, String dataType){
if ("Double".equalsIgnoreCase(dataType)) {
doStuff2(Double.valueOf(obj.toString()));
} else if ("Integer".equalsIgnoreCase(dataType)) {
doStuff2(Integer.valueOf(obj.toString()));
}
}
public void doStuff2(double d1){
//do some double related stuff here
}
public void doStuff2(int d1){
//do some int related stuff here
}
I'd like to do this without if/else, with something like this;
Class<?> theClass = Class.forName(dataType);
The problem is 'theClass' still can't be cast to either double or int. I would be gratefull for any ideas.
Thanks.
Found a related thread; Overloading in Java and multiple dispatch
This is not just a problem of dealing with primitive types.
Which method to call is decided in compile time, that is, if you want to be able to call different methods depending on the type of the arguments, you'll need several calls (i.e. you need the if-construct).
In other words, it wouldn't work even if doStuff2 took Integer and Double as arguments (your code is basically as good as it gets).
(In fancy words, this is due to the fact that Java has single dispatch. To emulate multiple dispatch you either need to use conditional statements or a visitor pattern.)
Since the method call is decided at compile time as the another answer told you, overloading won't work for you. I think that this problem can be solved with inheritance. So you write a base class with yourMethod() and override it in your derived classes.
As aioobe says, the choice between overloaded methods is made at compile time based on the static types of the arguments.
If you want to simulate overload choice at runtime, you will need to do some complicated runtime analysis of the different possible methods. It would go something like this:
get all declared methods of the class that declared doStuff2.
filter out the methods whose name is not doStuff2.
filter out the methods whose argument type cannot be assigned from the (dynamic) type of the argument value.
of the remaining methods, pick the one that is the best match ... taking care to deal with "ties" as ambiguous.
This will be tricky to code, and trickier if you also throw in handling of primitive types. It will also make the method calls expensive.
Frankly, some kind of hard-wired dispatching is much simpler. If you don't like if / else tests (or switching on a String in Java 7), then you could do something like this.
Map<String, Operation> map = ...
map.put("Double", new Operation(){
public void doIt(Object obj) {
doStuff2((Double) obj);
}});
map.put("Integer", new Operation(){
public void doIt(Object obj) {
doStuff2((Integer) obj);
}});
...
map.get(typeName).doIt(obj);
... which at least allows you to "plug in" support for new types dynamically.
If you resort to reflection, you'll only have to deal specially with primitive types. So your technique can work, but with the addition of a few explicit tests. If you need to reflectively find a method that accepts a primitive double, use double.class.