I have classes as follows
public class Useful
{
public void f(Object a)
{
System.out.println("In base f");
}
public void g(String a)
{
System.out.println("In base g");
}
}
public class MoreUseful extends Useful
{
public void f(String a)
{
System.out.println("In derived f");
}
public void g(Object a)
{
System.out.println("In derived g");
}
}
I am trying to override base class method but I am changing the parameters in derived class.
in method MoreUseful.f() I am using subclass parameter (String) as against Object in base class.
in method MoreUseful.g() I am using superclass parameter (Object) as against String in base class.
Is it possible to override these way?
Which of the above two cases will be correct overriding?
No, that's not possible, and would be a violation of the LSP.
By inheriting from a class, you express that your subclass MoreUseful is actually a Useful and therefore exposes all the functionality that Useful exposes. If you removed the ability to invoke f with an object, you'd break that promise.
You are free to overload f so that you have an f(String s) method though.
The g() method is indeed overriden. f(), however, is not overriden - it's overloaded. An easy way to verify this is to add #Override on each method you intend to override - if it results in a compilation error, you aren't overriding properly.
Related
This question already has answers here:
Polymorphism in Overloaded and Overridden Methods
(4 answers)
Closed 6 years ago.
class PolymorphisomTest {
class Base {
public void doTest(double d) {
System.out.println("From Base");
}
}
class DerivedBase extends Base {
public void doTest(int d) {
System.out.println("From Derived Base");
}
}
public void use(Base base) {
base.doTest(3);
}
public void run() {
use(new Base());
use(new DerivedBase ());
}
public static void main(String []cmd) {
new PolymorphisomTest ().run();
}
}
Here doTest(double d) from parent class and doTest(int d) from subclass but when i call base.doTest(3) it always invokes parent class method even my object reference is different. what's the reason behind it?
doTest(double d) is a completely different method from void doTest(int d), because they have different parameter lists. There actually isn't any polymorphism there at all; DerivedBase is declaring a new method, not overloading Base.doTest. It's as if you had done this:
class Base {
public void doTest(double d) {
System.out.println("From Base");
}
}
class DerivedBase extends Base {
public void doSomethingElse(int d) {
System.out.println("From Derived Base");
}
}
Changing a parameter's type changes the method signature, and makes it a new method instead of overriding the parent class' method.
When you call base.doTest(3), the compiler is going to call doTest(double), because that's the only method of the Base class that matches the parameter. Because that method isn't overriden by anything, Base.doTest gets called.
To override a method you must match the method signature in the derived class. When you change from double to int you create a new method. From Defining Methods - The Java Tutorials,
Definition: Two of the components of a method declaration comprise the method signature—the method's name and the parameter types.
The #Override annotation can protect you from this specific class of error. You can do something like,
class DerivedBase extends Base {
#Override
public void doTest(double d) {
System.out.println("From Derived Base");
}
}
DerivedBase class inherited your doTest from base class. Now, it has 2 methods-
doTest (double d)
doTest (int d)
You have not overridden method but overloaded it by giving different parameter. If you need to override doTest add method with double as parameter.
Reason why it is not calling doTest (int d) is when we call from parent reference , it searches for method their during compile time and bind with same. And at runtime , its same method with same signature from object in hand.
Below example runs without any errors, can any one explain me how this works?, as interface doesn't contain any toString()/hashcode/equals method declaration how compiler will resolve method call?,as per my understanding toString()/hashcode/equals or Object class methods will be declared by default inside interface? please correct me if am wrong
interface int1
{
public void show();
}
class inttest implements int1
{
public void show()
{
System.out.println("inttest.show()");
}
#Override
public String toString()
{
return "tostring called";
}
}
public class MainClass1
{
public static void main(String[] args) {
int1 i=new inttest();
System.out.println(i.toString());
}
}
Any interface has all the public methods of the Object class (it either inherits them from a super-interface or declares them implicitly if it doesn't already declare them explicitly).
This makes sense, since any implementing class of any interface must be a (direct or in-direct) sub-class of the Object class, and therefore will inherit an implementation of all the Object methods.
9.2. Interface Members
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless an abstract method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.
As all objects extend Object and Object has a toString() you are calling that method.
I wrote a program in Java with 2 interface and a class.
Both the interface has the same method name.
In the main class i am implementing both the interfaces and called the method.
I want to know which interface method is called...
Here is the sample code :-
public interface A {
void print();
}
public interface B {
void print();
}
public class C implements A, B {
public static void main(String[] args) {
C c = new C();
c.print();
}
public void print() {
System.out.println("sample");
}
}
public interface A {
void print();
}
public interface B {
void print();
}
In the above code the interfaces A and B are abstract interfaces, because some/all methods are declared but not defined.
Hence in your C class you are not calling any of these two (which is straightforward, how would you be able to call a method which was never defined?). What you are doing is defining the print method (hence giving it a body), to call it afterwards (in main).
You call the class's method
public void print() {
// TODO Auto-generated method stub
System.out.println("sample");
}
It's C's print(). abstract methods don't have implementations and are not called per se, it's one of their implementations that's called.
You may want to look into what's called static binding and dynamic binding. In this case to the compiler & runtime everything is at compile time, so the former is employed. Basically it will be statically determined that the method / implementation you want to call is C's print().
Dynamic binding would still mean calling a concrete implementation of a method, so it wouldn't choose an interface method per se, but the choice of which method to call will be done at runtime.
Interface which is implemented first in a way that interface's method will call and if another interface is next to the first one have same method name that will not going to call at all.
Java code:
class P {
public void hello() {}
}
class C extends P {
public void hello(String s) {}
}
My question is: Is the hello in class C overloading the one with same name in super class P?
My friend says they are not because the are not in the same class.
Taking a more formal approach, the Java Language Specification for Java 7 states:
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.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.9
I would point your friend to this link.
So, in short, in your example, the hello method is indeed overloaded.
Simple Explanation:
I think this question arises because at times we hear the following,
"Method overloading is performed within class.
Method overriding occurs in two classes that have inheritance relationship."
The above statement is correct. But your friend is wrong. why?
Because when you extend a class, the subclass have all the methods defined by superclass. It is as if all the methods of superclass have been implemented by the subclass. That means the hello() method has been implemented by the class C as well. Now, you added a method in class C with different parameter (hello(String s)). That means, class C has two methods in all with same name but different parameters and that is "overloading".
Hope it is crystal clear.
Overloading can happen in same class as well as parent-child class relationship whereas overriding happens only in an inheritance relationship.
Yes, your friend is wrong because he thinks only of the concept of overriding.
But here hello(), and hello(String s) are different by there parameters so it's overloading not overriding.
Source of confusion: Your friend would be right if speaking about C++ not Java. In C++, function overloading can only occur between members of the same class. Whereas in Java, overloading can occur, in addition to that, across two classes with inheritance relationship.
Yes it is overloading, This overloading is happening in case of the class 'C' which is extending P and hence having two methods with the same name but different parameters leading to overloading of method hello() in Class C. However Class P is only able to access one of the methods which is present in its own definition.
Long story short, an instance of C will have both the hello() and the hello(String s) methods available. An instance of P will only have the hello method available.
This is indeed overloading, as you have two methods of the same name taking different parameters.
However, it is not overriding, because overriding is having a method declared in a subclass with the same name and same parameters as a method in a superclass.
E.g. if you had
class C extends P {
public void hello() {}
}
it would be overriding the hello() method declared in P. When invoking new C().hello() in that case, you would invoke the implementation of the hello() method declared in class C.
It is a valid question since usually, overloading is explained using two methods with the same name (but different parameters) in the same class.
I would argue that yes, the method hello in C is overloading P's hello method because of the "is a" relation.
The "is a" relation states that since C subclasses P, it is also an instance of P ("C is a P"). Hence C has 2 overloaded hello-methods.
Good question!!!In sub class if method name | parameter type | list is changed then sub class method will not be considered as overriding it is considered as overloading method
Example :
class A{
void m1(int a){}
}
class B extends A{
void m1(float f)
{}
}
In above program m1 method is a overloaded method.
Yes we can overload the super class method in sub class like as bellow:
public class OverLoading {
public static void main(String[] args) {
B b = new B();
b.display();
b.display(4);
}
}
class A {
public void display() {
System.out.println("A class display method");
}
}
class B extends A {
public void display() {
System.out.println("class B subclass");
}
public void display(int a) { //Overloading in subclass
System.out.println("class B subclass with overloading");
}
}
Output:
class B subclass
class B subclass with overloading
Depends on the class. From class P's perspective (if the reference is P, the object can be of C) it is not. If you write something like: P p = new C(); there is no overloading because you cannot call p.hello("foo").
From class C's perspective it is overloaded because if you write C c = new C(); it has two methods with same name and different signatures.
This is a good question and the answer is a bit tricky.
Well, it's true that you can overload an inherited method from a parent class into a subclass. However, and here's the interesting part, the actual behavior depends on the reference variable type.
Let's consider the following example:
public class OverLoadingTest {
public static void main(String[] args) {
ChildClass cc = new ChildClass();
SuperClass sc = cc;
sc.method("lol");
cc.method("lol");
}
static class SuperClass {
public void method(Object o) {
System.out.println("SuperClass called.");
}
}
static class ChildClass extends SuperClass {
public void method(String s) {
System.out.println("ChildClass called.");
}
}
}
So, we have a class extending another and with a method that overloads a method from the parent.
It's easy to guess that if you have an instance of ChildClass, the two methods are overloaded, and overloading resolution takes place as it normally does.
However, let's consider creating an instance of ChildClass and assigning it to a reference variable of type SuperClass. Is the overloading thing still standing?
If you execute this program you will get this outptut:
SuperClass called.
ChildClass called.
The output clearly indicates that there's no overloading here in this case. This however can be altered by overriding the original method.
static class ChildClass extends SuperClass {
public void method(String s) {
System.out.println("ChildClass called.");
}
public void method(Object o) {
System.out.println("ChildClass called.");
}
}
Now, if you run the program again, you get this output:
ChildClass called.
ChildClass called.
Explanation
Now, why is JVM behaving that way? Why can't it see the overloading method as we're using an instance of the child class?
This takes us to how does JVM call a method. The JVM sees that you're referring to the object with a reference of type SuperClass, so, it can only use the methods that are related to that type, with the only exception is overriden methods. And since method(String) isn't overriding, we have method(Object) of the parent, hence, it's the one chosen for execution.
We then override the method to break this rule, and this is how the JVM called ChildClass.method(Object) even if the reference variable is of a parent class.
Overloading is when you have two methods that have the same name but different signatures (Your case).
Side note: Overriding is when you have two methods that have exactly the same signature and name and the parent class.
In the below code , can I say class B has overloaded add method ?
class A
{
public void add()
{
//some code
}
}
class B extends A
{
public void add(int a)
{
// some code
}
}
Nods
Yes, that's an example of method overloading. An example of method overriding would be,
class B extends A{
#Override
public void add(){
// do stuff
}
}
From the perspective of the API exposed by B, an add method already exists, even if provided by the superclass. Since you provide another add method with different arguments, this is overloading. To have provided the same signature would have been overriding.
Yes this is method overloading.
Yes. Consider this more straightforward example of overloading:
class A
{
public void add()
{
//some code
}
public void add(int a)
{
//this method is overloading add() from within its own class
}
}
Now, since B, in your example code extends A, it inherits add() and so it's safe to say that even though add() is not explicitly defined in B, the method is available, and so defining add(int a) may be considered overloading of add()
Yes, you can say that class B has overloaded the method add(). As public void add() is already present in class B, due to inheritance. Creating a method with same name, but a different signature (ie. the number, type, and order of the parameters) is overloading.