Why should we override a method? [duplicate] - java

This question already has answers here:
Why is method overloading and overriding needed in java? [duplicate]
(2 answers)
Closed 8 years ago.
Recently I was asked this question "why should one override a method? "
I replied, if I have a class with 10 methods and I want to use all of its functionality except one method, then I will override that method to have my own functionality.
Then the interviewer replied in that case why cant we write a new method with a different name and use that method instead.
Yes this is also right. Now I am confused. What is the real objective in overriding a method?
Can anyone please tell me? Thank you all in advance.

If you will give another name to the method in derived class, you cant invoke it with same interface. You can always invoke it through base class pointer.
i.e.
Base p = new Derived();
p.overrideMethod();
If Derived class is derived from Base then it will automatically call the derived version and not of Base. In case of different name, it is not possible. It is called code against interfaces and not implementations.

.
why cant we write a new method with a different name and use that method instead
It is because we want to use polymorphism. You could tell the interviewer this example: There is a module that calls specific methods on objects you give it; now imagine you can't change that module (e.g. no source). You can't tell it to use a different method but you can give it an object of a subclass which has overridden that method. To the module it will appear that nothing changed.
In practice it is also often the case that you could change that module but dont want to.

I replied, if I have a class with 10 methods and I want to use all of
its functionality except one method, then I will override that method
to have my own functionality.
=> Very often a way to break the Liskov Substitution principle ... => very bad OO design
You have many examples on the web of this "break" but a you can find a good explanation here.

The benefit of overriding is: ability to define a behavior that's specific to the subclass type which means a subclass can implement a parent class method based on its requirement.

One uses interfaces to allow for multiple implementations and one uses overriding to simplify the implementation of an interface (e.g. when implementing a WindowListener, one typically extends and overrides a method of WindowAdapter so that one does not need to provide definitions for the cases where the default behavior is sufficient). Adding a new method rather than overriding would not work in this case, because the caller understands the interface and invokes its methods; the whole point of overriding here is to change the behavior for the calls to the interface. If you simply added a new function, then the caller would have to know about it, which defeats the entire isolation between the consumer of a piece of functionality and the provider of that functionality which is what interfaces are intended to provide.

Overriding is a feature that is available while using Inheritance.
It is used when a class that extends from another class wants to use most of the feature of the parent class and wants to implement specific functionality in certain cases.
In such cases we can create methods with the same name and signature as in the parent class. This way the new method masks the parent method and would get invoked by default.

The main objective of overriding is code reuseablity which can be advatageous in big projects,it also provide flexiblity means you can pass different sets of input from any class and get the output

Related

#Override, with default methods in interfaces

I've been reading through some questions here on SO concerning the use of #Override in Java. (e.g. this one on override and this one on default methods, and obviously the documentations) However, I am still confused.
I was taught to always use and implement an interface when all behaviour in that interface needed to be used by a class. I get that. But as I was taught, you would do something like this (partially taken from the docs):
public interface TimeClient {
void setTime(int hour, int minute, int second);
}
Which is then implemented by a class.
public class TestSimpleTimeClient implements TimeClient {
public static void main(String[] args) {
}
#Override
public void setTime(int hour, int minute, int second) {
System.out.println(hour + " " + minute + " " +second);
}
}
The thing that bugs me is the implementation of the method in the interface. It doesn't do anything, it's only declared as a method that take arguments but doesn't do anything else. Then you take that method and Override it in a class that implements that interface.
I understand that this is a way to "force" classes to implement a method but I don't see how this is useful in some specific use cases.
Let's say I have an interface that's implemented by a couple of classes. I want most of these classes to share the same implementation of the method, but not all. The logical, and character-efficient way would be to have a way to say: these classes take the default method in the interface, but these classes override the default method. How would I go about doing that? Should the one that overrides the method only implement it, whereas the ones that simply use the default method as a whole extend it? And what if you only want this behaviour for a specific method in an interface?
The thing that bugs me is the implementation of the method in the interface. It doesn't do anything, it's only declared as a method that take arguments but doesn't do anything else.
That is not an "implementation of the method in the interface". That's just an interface method declaration. In programming, terminology matters. Interfaces tend to be devoid of any implementations. (Unless you are talking about the default interface methods of Java 8, but from the rest of your question it is unclear whether you are aware of their existence.)
I understand that this is a way to "force" classes to implement a class
A class cannot implement a class. A class extends a class. But a class implements an interface. In programming, terminology matters a lot.
It is not just a way to force classes to provide an implementation. It is also a way for callers to be able to invoke an interface method without having to know anything about the class that implements it.
but I don't see how this is useful in some specific use cases.
Well, take for example the Collection<T> interface, and the contains() method, which is implemented by a myriad of classes, among which ArrayList<T>, LinkedList<T>, HashSet<T>, BoundedBlockingQueue<T>, and so on, and so forth. Your code may look like this:
boolean hasPekingese( Collection<Animal> animals )
{
return animals.contains( AllOfMyAnimals.PEKINGESE );
}
Note how the hasPekingese() method does not have to know the exact class that is implementing Collection<Animal>. Which means that you may invoke hasPekingese() from a class which keeps its animals in an ArrayList<Animal>, and you may also invoke hasPekingese() from a class which keeps its animals in a BoundedBlockingQueue<Animal>. The method hasPekingese() does not know, and does not care.
Let's say I have an interface that's shared by a couple of classes.
It is unclear what you mean by "shared". Do you mean "implemented"? In programming, terminology is of paramount importance.
I want most of these classes to share the same implementation of the method, but not all. The logical, and character-efficient way would be to have a way to say: these classes take the default method in the interface, but these classes override the default method. How would I go about doing that?
There are many ways to go about that, the most common being to have some of these classes extend some common base class, which provides the common implementation of your method, so that the derived classes inherit this method, so they do not have to implement it. The rest of the classes do not extend that common base class, so each one of them has to provide its own implementations of that method.
Should the one that overrides the method only implement it, whereas the ones that simply use the default method as a whole extend it?
That's not clear. Also, please do not call it a "default method", because as of Java 8 "default method" is a term that has a very specific meaning, and although it is related to this discussion, it is different from the sense in which you are using it.
And what if you only want this behaviour for a specific method in an interface?
If a derived class wants the method to work differently, it may re-override it. Or, you may have two different base classes, one which implements the method in a certain way, and another which implements it differently, so half of your derived classes extend the first base class, while the other half of your derived classes extend the second base class.
Interfaces are like APIs. When some provider give you interface like List you don't think about if it is an ArrayList or other implementation, you just know what you can do with this object. Why? Because when you give an interface, you can change the implementation later, and don't worry that other part of code, that is using object through interface, will need changes.
I suppose that you think about things that should plug some behaviour to current class. These things can be called Traits in other programming languages, in another you have multiple inheritance. If you want some implemented logic that is propagated to your classes, you should use abstract classes in java with proper hierarchic. Remember that you can expand classes with inheritance or composition (open-closed principle).
Default methods in Interfaces (Java 8) can be tricky, because they cannot change state of the object. They might be some stubs or mathematics equation that only work with local and static context.

Implementing a method of interface is overriding or not in java

I know this might be crazy but today one of my friend puzzled by asking when we implement an interface in java is it considered as method overriding. I told him it is not overriding as we are providing working(definition) of method first time when we implement any interface. To support multiple inheritance java provide interface but he was not convinced and was arguing. Please bring some light on to the topic.
The term "overriding" applies when there is an existing implementation of the method . The correct term is "implementing" for interfaces and other abstract declarations.
The #Override tag is used for both cases - it is used when:
The method does override or implement a method declared in a supertype. --javadocs
And from Wikipedia:
Method overriding, in object oriented programming, is a language feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its superclasses or parent classes.
Note that interfaces can have default methods - redefining these methods overrides them:
When you extend an interface that contains a default method, you can ... redefine the default method, which overrides it.
Besides linking to "canonical" sources, I'm not sure what advice to offer on winning a semantic argument with your friend. Perhaps you could ask him what the distinction is between "implementing" and "overriding", and what word he would use instead of "overriding" for the concept of redefining an existing method.
At first glance, interfaces just define API. Since there is no super method to override, the implementations is the first method.
But since Java 5, it's customary to add #Override annotations even for methods which come from interfaces. The main reason here is to catch problems which happen when people change an interface: Now you have a method which is "dangling" - there is no API which says that the method has to be there. The annotation causes an error if you remove a method from the interface, catching this so you can properly clean up all the code.
But that still doesn't mean the implementing method overrides anything.
Except that an interface is very much an abstract class with abstract methods in the byte code. And abstract methods do override.
My feeling is that you can argue both ways but the argument is moot unless you have a use case there the answer to the question actually has a real impact on the code. And here, it doesn't really matter since the compiler hides all the ugly details.

Why we need default methods in Java? [duplicate]

This question already has answers here:
Purpose of Default or Defender methods in Java 8
(5 answers)
Closed 8 years ago.
I'm taking a look to Java 8 news compared to 7 and in addition to very interesting things like lambdas or the new time framework, i found that a new feature(?) was introduced: default methods.
I found the following example in this article:
public interface Math {
int add(int a, int b);
default int multiply(int a, int b) {
return a * b;
}
}
It seems very strange to me.
Above code looks like an abstract class with an implemented method. So, why to introduce default methods in an interface? What is the actual advantage of this approach?
In the same article I read this explaination:
Why would one want to add methods into Interfaces? We’ll it is because interfaces are too tightly coupled with their implementation classes. i.e. it is not possible to add a method in interface without breaking the implementor class. Once you add a method in interface, all its implemented classes must declare method body of this new method.
Well this doesn't convince me at all. IMHO I believe that when a class implements an interface obviosly must declare methods body for each method in it. This is surely a constraint, but it's also a confirm of its "nature" (if you understand what I mean...)
If you have common logic to every inheriting class you'll put it into an implementing abstract class.
So, what's the real advantage of a default method? (It looks more like a workaround than a new feature...)
UPDATE I understand that this approach is for backwards compatibility, but it still doesn't convince me so much. An interface represent a behaviour that a class MUST have. So a class implementing a certain interface has surely this behaviour. But if someone can arbitrarily change the interface, this constraint is broken. The behaviour can change anytime... Am I wrong?
This is for backwards compatibility.
If you have an interface that other people have implemented then if you add a new method to the interface all existing implementations are broken.
By adding a new method with a default implementation you remaining source-compatible with existing implementations.
For a slightly simple/contrived example that should hopefully demonstrate this let us say you created a library:
void drawSomething(Thing thing) {
}
interface Thing {
Color getColor();
Image getBackgroundImage();
}
Now you come to do a new version of your library and you want to add the concept of border colors, that's easy to add to the interface:
interface Thing {
Color getColor();
Color getBorderColor();
Image getBackgroundImage();
}
But the problem is that every single person using your library has to go back through every single Skin implementation they ever did and add this new method.
If instead you provided a default implementation to getBorderColor that just called getColor then everything "just works".
There have been a lot of methods acting on an abstract interface in the past. Before Java 8 they had to be put into an additional class pairing the interface, e.g. Collections with Collection.
This old approach was neither more convincing than default methods nor more practical. Instead of list.sort() you had to say Collections.sort(list). This also implies that you had to make a fundamental decision when creating an interface, either you require every List implementation to implement a sort method or you provide a sort method in a utility class that cannot be overridden.
With default methods you can have both, a standard implementation which the List implementations do not need to implement on its own but still can be overridden if a concrete implementation has a more efficient way to do it knowing its internals, e.g. ArrayList.sort passes its internal array directly to Arrays.sort skipping some intermediate operations.
Suppose at some point you want to add new functionality in declared interface, up to Java 7, If you will add a new method in declared an interface, you also have to define the implementation of the method in classes that are implementing that interface.
In java 8, You can add a default method containing the implementation and all the child class will inherit that method.
Edit : (After question update)
An interface represent a behaviour that a class MUST have
It still represent a behaviour that class must have, your confusion is how you are defining behaviour. All implementing class will inherit default method and are also free to write their own implementation. consider following two cases,
If implementing class does not provide own implementation and simply inherit default method. If you change behaviour of default method in interface, implementing classes will be having updated behaviour as they inherit default method so it holds An interface represent a behaviour that a class MUST have.
If implementing class provide own version of default method, and if you will change behaviour (only arguments) of default method. In this case implementing class will be having two overloaded methods, one which was earlier defined and second one is inherited default method. and if you change complete behaviour (arguments with return type also), It will create ambiguity in implementing class as you can not overload method by changing return type and Implementation will be broken. again it holds An interface represent a behaviour that a class MUST have.
Example :
Bulk data operation in collection is added in Java 8 (Reference : http://openjdk.java.net/jeps/107), to implement that forEach() method is added in Iterable interface. Adding abstract method in Iterable interface would break all the existing code because each class has to implement that method.
Solving the issue, following default forEach() method is added in Iterable interface,
interface Iterable
{
default void forEach(Consumer<? super T> action)
{
for (T t : this) action.accept(t);
}
}
Reference : Java 8 : Default method in Interface

Checking what subclass the object is in, then running a method in that subclass - Java

I have an abstract class called Policy, and two subclasses DepreciablePolicy and ExpirablePolicy
I have an array of Policy, policies[]
I want to check what subclass my object is in (if it's a Policy, DepreciablePolicy or ExpirablePolicy)
I did this by using this if statement.
if (this.policies[polNum] instanceof DepreciablePolicy){
For each type of subclass, there is a different method I have to run.
Only problem is that I'm only able to use the Policy methods, but not the subclass methods or constructors.
Is there a way I can do this?
This is inheritance done the wrong way. The whole point of polymorphism is that your code doesn't care which subclass an object is. Anything you need to do should be expressed through the Policy, which should really be an interface. Your code should interact with a Policy based on that interface, and the subclasses choose how to react.
That being said, you're probably looking for simple down-casting:
DepreciablePolicy d = (DepreciablePolicy) policy;
This is nothing better than a poor bandage on a bad design, though.
For each type of subclass, there is a different method I have to run.
Then you've misdesigned it. Define an abstract method in Policy, have all the derived classes implement it according to their own requirements. Then just call the method.

can a Java Interface change even though the client project won't be compiled again?

I am trying to change an interface in Proj2.
However, Proj1 is already using this interface, and won't be compiled with my new version.
Looks like problems occur only if I change/delete existing methods but adding new methods seems to be not causing any issues.
So as long as I only "add" methods to the interface, I can expect Proj1 to be fine with the latest Jar of Proj2.
Is that a rock solid safe assumption?
Update:
Both the interface and impl reside in proj2. Proj1 has no implementation of that that interface.
By "using," you mean "references an object using the interface and invokes interface-defined methods using that reference," not "implements the interface" (yes, you've clarified in comments, but I just want to repeat, because all the other answers are about implementing the interface).
In that case, as long as you have not removed methods from the interface or change their signature, your existing code will work.
The reason that this will work is that the compiler translates the method calls into an invokeinterface bytecode, which references the interface class and method by name. At runtime, the JVM simply validates that the actual reference implements the interface, and invokes the method.
If you remove or change a referenced interface method, one of two things will happen: either the JVM will refuse to load the class in proj1, because the interface reference could not be resolved, or it will give a NoSuchMethodError (I believe it's the second). Same thing if you remove or change a referenced method in a concrete class.
No. Adding new methods to the interface or updating its current signature would require you to provide the implementation of those methods in classes where you have implemented the interface.
However, when you remove a particular method declaration from an interface, even though it is defined in the class implementing the interface, there would be no effect. The removed method would just serve to be a normal method of the class, no longer tied with the existing contract of the interface.
The only way that I can think of solving your issue is to take the advantage of Java letting you implement multiple interfaces for a given class. What you should try to do is create a new interface, define your new methods over here and let your classes in proj2 implement this interface as well. This way, when you package your new jar, your existing classes in proj1 would remain unaffected.
If you're just adding methods, create a second interface. Java classes can implement more than one interface. That way, the classes that implement Interface1 remain the same.
Your newer class(es) implement interfaces Interface1 and Interface2.
you will get the error:
The type XXXImpl must implement the inherited abstract method IXXX.method()

Categories

Resources