Overloading Java Method from Inherited Interface - java

Question:
I have the following:
interface A
{
int MethodA(int x, int y);
}
and
interface B extends A
{
//This is meant to overload MethodA
int MethodA(int x, int y, int z);
}
The problem comes when I try to implement interface B, and run the method in main.
class Foo implements B
{
//For interface B
public int MethodA(int x, int y, int z)
{
//Actual implementation
}
//For interface A
public int MethodA(int x, int y)
{
//Actual implementation
}
}
public static void main(String[] s)
{
Foo foo = new Foo();
//Problem occurs here
foo.MethodA(1, 2, 3);
}
Eclipse will complain and say that "The method MethodA(int, int, int) in the type A is not applicable for the arguments (int, int)."
But why? I've already implemented interface B. Shouldn't MethodA(int, int, int) have overload MethodA(int, int), making MethodA able to accept three integers as well?

The above looks a little confused.
You need to specify your return types, specify names for each argument (even in the interface) and declare the implemented methods as public eg.
public int MethodA(int a, int b, int c)
{
//Actual implementation e.g.
return 0;
}
Your static main() method has to reside within a class (e.g. the Foo class above), and finally call the method with real arguments.
Once you've done that, then all should be good. You can certainly provide overloading as in the above. You just need to resolve the more basic issues first. I would get a very basic single method going, and then enhance from there in order to get something working.

Related

Avoid code duplication over classes

I am writing some classes and all of them implement a certain method they inherit from an interface. This method is close to the same for all the classes beside one call to a certain other function.
For example:
public void doSomething(){
int a = 6;
int b = 7;
int c = anOtherMethod(a,b);
while(c < 50){
c++;
}
}
What if multiple classes have the function doSomething() but the implementation of the method anOtherMethod() is different?
How do I avoid code duplication in this situation? (This is not my actual code but a simplified version that helps me describe what I mean a bit better.)
This looks like a good example of the template method pattern.
Put doSomething in a base class.
Declare abstract protected anotherMethod in that base class as well, but don't provide an implementation.
Each subclass then provides the proper implementation for anotherMethod.
This is how you could implement the technique that Thilo talked about in the following demo:
Main class:
public class Main extends Method {
public static void main(String[] args) {
Method m = new Main();
m.doSomething();
}
#Override
public int anOtherMethod(int a, int b) {
return a + b;
}
}
Abstact class:
public abstract class Method {
public abstract int anOtherMethod(int a, int b);
public void doSomething() {
int a = 6;
int b = 7;
int c = anOtherMethod(a, b);
System.out.println("Output: "+c);
}
}
This way, all you have to do is override anOtherMethod() in each class that you want to use doSomething() with a different implementation of the method anOtherMethod().
Assuming every version of anOtherFunction takes two integers and returns an integer, I would just have the method accept a function as an argument, making it Higher Order.
A function that takes two arguments of the same type and returns an object of the same type is known as a BinaryOperator. You can add a argument of that type to the method to pass a function in:
// Give the method an operator argument
public void doSomething(BinaryOperator<Integer> otherMethod) {
int a = 6;
int b = 7;
// Then use it here basically like before
// "apply" is needed to call the passed function
int c = otherMethod.apply(a,b);
while(c < 50)
c++;
}
}
How you use it though will depend on your use case. As a simple example using a lambda, you can now call it like:
doSomething((a, b) -> a + b);
Which simply returns the sum of a and b.
For your particular case though, you may find that having doSomething as part of a Interface isn't necessary or optimal. What if instead, anOtherMethod is what's required to be supplied? Instead of expecting your classes to supply a doSomething, have them supply a BinaryOperator<Integer>. Then, when you need to get results from doSomething, get the operator from the class, then pass it to doSomething. Something like:
public callDoSomething(HasOperator obj) {
// There may be a better way than having a "HasOperator" interface
// This is just an example though
BinaryOperator<Integer> f = obj.getOperator();
doSomething(f);
}

Method overloading with both static and non-static methods

As I've learned, in Java method overloading, we use same name for all overloaded methods. And also, their return type is not a matter. But what happens if we use same method as static and non-static form, as in the below example? Can we consider this method overloading?
class Adder {
static int add(int a, int b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
}
class Test {
public static void main(String[] args) {
Adder a1 = new Adder();
System.out.println(Adder.add(11, 11));
System.out.println(a1.add(11, 11, 51));
}
}
I read some articles, but they didn't clarify my question.
Use of keyword static doesn't make a difference in method overloading.
Your code compiles because the method signature of both add() methods are different (2 params vs 3 params).
However, if you were to write something like this, then it would result in a compilation error.
class Adder {
static int add(int a, int b) {
return a + b;
}
int add(int a, int b) {
return a + b;
}
}
Yes they can overload each other. See this JLS :
If two methods of a class (whether both declared in the same class, or
both inherited by a class, or one declared and one inherited) have the
same name but signatures that are not override-equivalent, then the
method name is said to be overloaded.
See this Thread .
U have two methods one is static and another is non static.. so this is not overloading... Because both methods get stored in memory saperately...

Can somebody explain why do I get this when I run the program? (simple Java polymorphism)

So, I have these 3 classes in Java.
When I run the program I get:
20,
15,
10,
My question is, why do I get this instead of:
15,
20 (doesn't public int getX(); in class B get us to 15+5=20?),
10
for example?
Can you please explain to me , step by step, what really happens in this program because I am very confused with the output(and the sequence).
public class A {
private int x = 15;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public void printX() {
System.out.println(this.getX());
}
}
Child:
public class B extends A {
private int x = 5;
#Override
public int getX() {
return super.getX() + x;
}
#Override
public void setX(int x) {
super.setX(x);
super.printX();
}
#Override
public void printX() {
System.out.println(super.getX());
}
}
and
public class C {
public static void main(String[] args) {
A a = new B();
System.out.println(a.getX());
a.setX(10);
a.printX();
}
}
This is happening because you instantiate a as a B object - A a = new B(). It doesn't matter that the explicit type of a is A; it's more generic (abstract) than its real type B (because B inherits from A), therefore polymorphism calls B methods (more specific) in first order. The same applies to fields.
After calling a.getX() class B references to A's getX(), which returns its 15 (superclass method has no reference to the object it was called from in this case), then 5 (B's x) is added, resulting in 20.
The subsequent calls behave in a similar manner.
I have given a basic example similar to your problem go through it you will get your answer. This is the concept of runtime polymorphism
Inheritance creates typecompatibility. It allows a super class reference to refer to the object of sub class. (Reverse is not true).
A super class reference, that refers to object of sub class, can only be used to access the inherited and overrridden methods of sub class. The members newly defined in sub class are not accessible using reference of super class.
class A
{
void f1()//this holds address of object of B
{
System.out.println("A f1");
}
void f2()
{
System.out.println("A f2");
}
}//A
class B extends A
{
void f3()//new method
{
System.out.println("B f3");
}
void f2()//this holds address of object of B
{
System.out.println("B f2 starts");
f3(); //this.f3()
System.out.println("B f2 ends ");
}
}//B
class TypeCmptbl
{
public static void main(String args[])
{
A ref; //reference of A
ref = new B();//Object of B
//ref.inherited() allowed
ref.f1();
//ref.overridden() allowed
ref.f2();
//ref.newMembersOfChild() not allowed
//ref.f3();
}//main
}
Consider the statement
ref.f2();
Here ref is a reference of class A and it has address of object of class B f2() is a overridden method.
When compiler detects such a statement then it doesn't bind the function call with any definition. It only validates the call.
Binding of such calls is left for the runtime environment. At program runtime system identifies the datatype of the object and binds the function call with the function definition provided by the class of object. This type of binding between the function call and function definition is called as "runtime polymorphism" .
Your question is related to the runtime polymorphism in java note that methods are bind at runtime, and the variables are bind at Compile time
In your example
public class C {
public static void main(String[] args) {
A a=new B();
System.out.println(a.getX());
a.setX(10);
a.printX();
}
}
// reference is of A but the object is of B, so at runtime JVM see that memory is of B so the B's method is called, this is runtime Polymorphism
when the below statement is called , the getX() of class B is invoked.
System.out.println(a.getX());
#Override
public int getX() {
return super.getX() + x; // this will add 15 from class A + 5 in this method.
}
the above statement displays 20
when the below statement is called,
a.setX(10);
#Override
public void setX(int x) {
super.setX(x); // observe this method, this prints 15
super.printX(); // this prints 10
}
//super.setX(x); it will call
public void setX(int x) {
this.x=x; // 10 <--- 15 so 15 is displayed
}
here this.x refers the value which is passed through a.setX(10).
A a = new B();
So the concrete type of a is B.
System.out.println(a.getX());
You're calling getX() on an object of type B. So the following method is called, because the concrete type of a is B, and B has overridden the getX() method defined by A:
public int getX() {
return super.getX() + x;
}
It adds B's x (whose value is 5), with the result of super.getX(). This method, in A, is defined as
public int getX() {
return x;
}
So it returns A's x, which is initialized to 15.
The result is thus 5 + 15 = 20.
The rest can be explained the same way. Remember that fields are not accessed in a polymorphic way. Only methods are. So, inside the code of A, when you see x, it always mean "the value of the field x in A". Inside the code of B, when you see x, it always mean "the value of the field x in B".
When you say:
A a = new B();
it means Object of A is instantiated with class B. So, in the memory, a space is reserved for your object 'a' which contains all the methods and properties of class B (not A).
So, when the first print statement is executed, it executes the getX() method of the class B and not the getX() method of class A.
For other methods called by your object 'a', the methods of the class B are called.
This is also known as dynamic binding, as JVM allocates the memory to the object 'a' at the run time and not compile time.
For more details on dynamic binding check these links:
http://www.tutorialspoint.com/java/java_overriding.htm
http://www.tutorialspoint.com/java/java_polymorphism.htm
I also suggest you to instal eclipse on your machine and run your code in the debug mode.
This is the best way you can study your code.

Which of the following methods will be legal in the subclass?

I am confused about how to create methods in a subclass. I am hitting my head against a brick wall with this and not even sure how to word the question.
import java.io.*;
public class A {
public double method1(double x, double y) { return 1.0; }
}
class B extends A {
//subclass method to be placed after this line
}
public double method1(double x, double y) { ... }
public int method1(double x, double y) { ... }
public double method1(int x, int y) { .... }
public int method1(double x, double y, double z) { ... }
Which of the following methods will be legal in the subclass and why?
Overrides method1 with new functionality.
Illegal because it has the same parameter signature but a different return type.
3,4. legal but are really separate methods.
Just consider the argument types to be part of the method name:
Only if the name plus the argument types fully match, you override the same method with new functionality. In this case, the return type must match (starting with Java 1.5, the return type may be specialized in subclasses, see https://blogs.oracle.com/sundararajan/entry/covariant_return_types_in_java)
In other cases, the added methods are just separate methods with the same name. Java statically picks the right one for each invocation at compile time based on the provided argument types. If arguments are compatible and the names are the same for multiple methods, it picks the closest match.
If you put the following methods in class, as per my understanding, this should happen:
public double method1(double x, double y) { ... }
This is overridden method, which means you overriding the behavior of method1 in your subclass, which is perfectly legal.
public int method1(double x, double y) { ... }
Compilation error: This is a try to do method overloading but not in a legal way. Method overloading allows to have same method name but different type/number of arguments. Method overloading is done with different parameter list but NOT by using a different return type.
public double method1(int x, int y) { .... }
This one is a legal overloaded method
public int method1(double x, double y, double z) { ... }
Again a legal overloaded method
Overrides the method in A and is legal
Is illegal because returntype is different and not a specialisation of the returntype of the method in A
Is an overloaded method because the argument types are different
Is an overloaded method because there are more parameters
See also http://en.wikipedia.org/wiki/Function_overloading and http://en.wikipedia.org/wiki/Method_overriding
Legal overriding
Not Legal overriding because return type should be covarient or same
legal overloading
legal overloading
overriding rules :- * parameter must same
return type must same or it should be covarient
exception if it is checked it should be sub class of that overridden method
access modifier should be same or less restricted
overloading rules :- * parameter must different
return type can be same
access modifier can be same
Read Katherine Sierra, Bert Bates (SCJP Book) for full rules or Java doc

Should I use Objects to avoid method overloading or method overloading is better?

I have two interface structures.
MyInterface1
public interface MyInterface1{
public Object SUM(Object O,Object P);
}
MyInterface2
public interface MyInterface2{
public int SUM(int O,int P);
public double SUM(int O,double P);
public double SUM(double O,double P);
public double SUM(double O,int P);
}
Which is a better design approach to implement the interface so that code efficiency is maintained?
The second approach (overloading) is much more preferred since it contains method signatures that are strongly typed.
Think about the following code.
public class InterfaceImpl implements MyInterface2{
public Object SUM(Object O,Object P){
//Really what can I do here without casting?
/* If I have to cast, I might as well define
types in the method signature, guaranteeing
the type of the arguments
*/
//Lets cast anyway
return (Integer) O + (Integer) P;
}
public static void main(String[] args) throws ParseException {
System.out.println(SUM(1,2)); //Excellent Returns 3
//Yikes, valid arguments but implementation does not handle these
System.out.println(SUM(true,false)); //Class cast exception
}
}
Conclusion
As more types are encountered that the method needs to handle, the implementation will be forced to perform type checking before doing the necessary casts. In theory type checking would need to occur for every class that extends Object, since the method signature only restrains arguments to the type. Since the arguments are objects there will be an infinite amount of types to check, rather impossible.
By using overloaded methods you express the intent of the method as well as restrict the set of allowable types. This makes writing the implementation of the method much easier and manageable, since arguments will be strongly typed.
As the other answers already mentioned, overloading is better.
But I would also add that you don't need 4 versions, only 2:
public interface MyInterface2 {
public int SUM(int O, int P);
public double SUM(double O, double P);
}
If you call SUM with an (int,double) or (double,int) the int will get upcasted to a double and the second of the methods is the one that will run.
For example, the code below compiles and prints "goodbye":
public class Test implements MyInterface2 {
public int SUM(int o, int p) {
System.err.println("hello");
return o + p;
}
public double SUM(double o, double p) {
System.err.println("goodbye");
return o + p;
}
public static void main(String[] arg) {
Test t = new Test();
t.SUM(1.0, 2);
}
}
In this case second option is good. But it varies from code to code. Example
interface InterfaceFrequencyCounter
{
int getCount(List list, String name);
}
interface AnotherInterfaceFrequencyCounter
{
int getCount(ArrayList arrayList, String name);
int getCount(LinkedList linkedList, String name);
int getCount(Vector vector, String name);
}
so now in above given case second option is not good practice. First one is good.
Overloading is better, as you don't want someone to call you method with a String or something.
What you can do, is using a common super class if you have one (Number in your case - if you wish to get Long and Float too).
For safe code method overloading better approach.
Overloading is better as described above.
If you run into a situation described by AmitG, you should use interfaces and not just the most generic object type. Anyways, your method almost always can work properly with only some subset of objects, not all of them. In that case you need to find a common interface and use it in a method signature, just like AmitG did in his example. The use of interface shows your intent to method cliens clearly, it's typesafe and removes the need to do casting inside the method.

Categories

Resources