This question already has answers here:
What does it mean to "program to an interface"?
(33 answers)
Closed 6 years ago.
SuperClass object = new SubClass();
Why use a superclass to instantiate a subclass object like above? Because the only way i learnt to instantiate an object is to:
SubClass object = new SubClass();
I'm learning java.
You may have a method that only takes an instance of SuperClass. Since SubClass is a SuperClass, you can use an instance of SubClass and treat it as SuperClass.
The same behavior is used when working with interfaces:
List someList = new ArrayList();
That's the beauty of polymorphism. It allows you to change out the implementation of the class' internals without breaking the rest of your code.
This is known as polymorphism.
Imagine the following example:
Musician musician = new Pianist();
or
Musician musician = new Drummer();
Suppose Musician class has a method: play(). It doesn't matter who the musician is, if you call play method, you'll know how to play the determined instrument, base on concrete class, on this case, no matter if Pianist or Drummer.
Each concrete class, overwriting its play() method, can play on your own:
e.g. for Pianist class: play() { playsBeethoven(); }
For detailed information, please check http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
It's always good to remember to use it with inheritance http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
The main reason to do the former is for function calls that expect the super class. If you have a class A that has a method like this
public static void insert(SuperClass b) {
//do something
}
and you have the
SuperClass object = new SubClass();
you can do
A.insert(object);
But if you do
SubClass object new SubClass();
you can't do
A.insert(object);
unless you add a method like this to A
public static void insert(SubClass b) {
//do something
}
This helps you cut down on redundant or copied code and keep things cleaner.
All you're doing is telling the JVM what the type of the reference is at compile time.
In the first case, you're saying that the object reference has static type of the super class. When you create a new sub-class object, you can have that reference point to it because a sub-class IS-A super class instance.
That is one of the main reasons you use inheritance. You treat the SuperClass as an abstraction, and at compile time you don't need to know the derived type, or another class doesn't need to know the derived type. This allows you to use references to SuperClass while using polymorphism to call the methods of the derived class.
This enables you to
a.) Create factories so that you don't need to know the type at compile time, and you have some runtime method that creates the derived types. Think COM, GStreamer, DirectShow, Glib, etc...
b.) Hide complexity to other objects by only exposing the base type references even though they are instances of the derived type. Think about the methods that return object or take an object reference as an argument.
c.) many more possibilities, but those are probably the most relevant two uses to you.
Related
This question already has answers here:
In Java, why does ((A)b).disp() call derived class method disp() instead of base class method disp() ?
(4 answers)
Closed 3 years ago.
I am learning more about polymorphism and casting in Java. I was running some code and I am quite confused with the output. I would really appreciate it if someone can explain what the compiler is doing here.
When I wrote this code, I thought that since newCar() is being cast to Vehicle, I assumed it would use the default method that was written in the Vehicle interface. But it looks like it used the overridden method in Car.
Thanks in advance!!
public interface Vehicle {
default boolean canFly() {return true;}
}
public class Car implements Vehicle {
boolean canFly() {return false;}
public static void main(String[] args) {
Vehicle vehicle = (Vehicle) new Car();
System.out.println(vehicle.canFly());
}
}
I saw possible duplicates; however, the question was targeted to only classes. My question is specifically with interfaces.
The whole point of inheritance and polymorphing is that it doesn't matter what type the variable has, the actual type of the created object determines which method will be called.
There is no way for you to call the Vehicle version of the canFly method, since it has been overridden by the Car class, and the real object is a Car.
The Lambda faq lists conflict resolution rules for default methods. First rule is:
Classes always win. A declaration in the class or a superclass takes priority over any default method declaration.
Because the class provides an implementation of the method, that always takes precedence over the default method on the interface. ("Default" means a fallback for cases where no implementation is provided otherwise.)
Casting only keeps the compiler from reporting an error due to some variable's type not matching the type of the thing being assigned to it. It's there for cases where you know it's ok to treat something as another type and you need to overrule the compiler. Casting has no effect at runtime, except to cause a ClassCastException to be thrown if the cast is erroneous. See here for more details.
TLDR: The idea that you could use casts to change what method gets called is not accurate.
I have a method (prepareErrorMessage) that accepts objects of type ErrorMessagePojoSuperclass. However, I only pass subclasses of ErrorMessagePojoSuperclass as arguments:
public class ErrorMessagePojoBundle extends ErrorMessagePojoSuperclass {}
public class Tester {
ErrorMessagePojoBundle empb = new ErrorMessagePojoBundle();
prepareErrorMessage(empb);
public void prepareErrorMessage(ErrorMessagePojoSuperclass errorMessagePojo) {
String errorStatusMsg = messageConverter.convertXMLToString(errorMessagePojo);
}
}
The class ErrorMessagePojoBundle has more methods than its superclass.
I need to make sure that when the line of code is running messageConverter.convertXMLToString(errorMessagePojo), messageConverter processes an instance of the subclass - in this case the object empb. Any ideas? I want to solve this without the use of casting. Thank you.
Any ideas? I want to solve this without the use of casting.
Your options are:
Defining an interface with the necessary method, having the subclass implement it, and using that interface as the parameter type rather than the superclass.
Changing the parameter type to the subclass, not the superclass.
instanceof and casting (not usually what you want to do).
1 and 2 are basically just variants of each other.
In your example code, there's no reason for prepareErrorMessage to accept the superclass rather than the subclass (or an interface), since the only thing it does can only be done with the subclass (or something implementing the same interface).
Let's say I have a superclass BigClass, and the subclass LittleClass inheriting from it. BigClass has a method DoThing(), and LittleClass has an overriding DoThing() method with different functionality.
Does it make a difference in any way to instantiate the subclass like this:
BigClass myNewClass = new LittleClass();
or this:
LittleClass myNewClass = new LittleClass();
I can see why the first one would be more useful as you can declare a lot of different subclasses in one line ect, but other than that is there any difference?
The BigClass reference has access only to BigClass functionality, regardless of where it's implemented (e.g., BigClass or LittleClass). In other words, if LittleClass has a method that isn't overriding something from BigClass you cannot call it with the BigClass reference.
At runtime there's no difference (in the sense you mean it). Your myNewClass variable is pointing to an object of type LittleClass in both scenarios. Any methods you call on it will be executed in the derived class (LittleClass), if it overrides them explicitly. If it does not, they will be searched/called in the super class, if not in its super class and so on.
The difference is at compile time. If on the next line you try calling some method method defined by LittleClass only (but not by BigClass), this will not compile in the first scenario but will compile in the second scenario.
As far as DoThing() method goes there's no difference.
Now, let say LittleClass class has DoEverything() method that was not inherited, since it's not even present in superclass.
I such case, myNewClass.DoEverything() will be legal only in your 2nd case (with reference variable of LittleClass() type).
First one is useful as you can have polymorphic behavior using base class handler. If you know that the Base Class handler will always have this Derived Class object only, Having Handler of either base class or derived class makes not much difference.
Another difference would be that Base class handler can't access Non Abstract Methods implemented in Derived Class.
The difference only be in the first scenario
BigClass myNewClass = new LittleClass();
you can only use
myNewclass
object to access methods belong to the superclass.
One example is Factory design pattern :
In factory pattern , you would have a method that creates various subclasses depending of user need and return the type would be BigClass in this case.
Example :
class Factory {
public BigClass getInstance(int type) {
switch(type) {
case BMW: return new LittleClass() ;
case AUDI: return new Child2() ;
DEFAULT: return new BigClass();
}
}
}
To use this:
BigClass obj = factory.getInstance(AUDI);
obj.getPerformanceIndicators();
We always say that method overloading is static polymorphism and overriding is runtime polymorphism. What exactly do we mean by static here? Is the call to a method resolved on compiling the code? So whats the difference between normal method call and calling a final method? Which one is linked at compile time?
Method overloading means making multiple versions of a function based on the inputs. For example:
public Double doSomething(Double x) { ... }
public Object doSomething(Object y) { ... }
The choice of which method to call is made at compile time. For example:
Double obj1 = new Double();
doSomething(obj1); // calls the Double version
Object obj2 = new Object();
doSomething(obj2); // calls the Object version
Object obj3 = new Double();
doSomething(obj3); // calls the Object version because the compilers see the
// type as Object
// This makes more sense when you consider something like
public void myMethod(Object o) {
doSomething(o);
}
myMethod(new Double(5));
// inside the call to myMethod, it sees only that it has an Object
// it can't tell that it's a Double at compile time
Method Overriding means defining a new version of the method by a subclass of the original
class Parent {
public void myMethod() { ... }
}
class Child extends Parent {
#Override
public void myMethod() { ... }
}
Parent p = new Parent();
p.myMethod(); // calls Parent's myMethod
Child c = new Child();
c.myMethod(); // calls Child's myMethod
Parent pc = new Child();
pc.myMethod(); // call's Child's myMethod because the type is checked at runtime
// rather than compile time
I hope that helps
Your are right - calls to overloaded methods are realized at compile time. That's why it is static.
Calls to overridden methods are realized at run-time, based on the type on which the method is invoked.
On virtual methods wikipedia says:
In Java, all non-static methods are by default "virtual functions." Only methods marked with the keyword final are non-virtual.
final methods cannot be overridden, so they are realized statically.
Imagine the method:
public String analyze(Interface i) {
i.analyze();
return i.getAnalysisDetails();
}
The compiler can't overload this method for all implementations of Interface that can possibly be passed to it.
I don't think you can call overloading any sort of polymorphism. Overloaded methods are linked at compile time, which kind of precludes calling it polymorphism.
Polymorphism refers to the dynamic binding of a method to its call when you use a base class reference for a derived class object. Overriding methods is how you implement this polymorphic behaviour.
i agree with rachel, because in K&B book it is directly mentioned that overloading does not belong to polymorphism in chapter 2(object orientation). But in lots of places i found that overloading means static polymorphism because it is compile time and overriding means dynamic polymorphism because it s run time.
But one interesting thing is in a C++ book (Object-Oriented Programming in C++ - Robert Lafore) it is also directly mentioned that overloading means static polymorphism.
But one more thing is there java and c++ both are two different programing languages and they have different object manipulation techniques so may be polymorphism differs in c++ and java ?
Method Overloading simply means providing two separate methods in a class with the same name but different arguments while method return type may or may not be different which allows us to reuse the same method name.
But both methods are different hence can be resolved by compiler at compile time that's is why it is also known as Compile Time Polymorphism or Static Polymorphism
Method Overriding means defining a method in the child class which is already defined in the parent class with same method signature i.e same name, arguments and return type.
Mammal mammal = new Cat();
System.out.println(mammal.speak());
At the line mammal.speak() compiler says the speak() method of reference type Mammal is getting called, so for compiler this call is Mammal.speak().
But at the execution time JVM knows clearly that mammal reference is holding the reference of object of Cat, so for JVM this call is Cat.speak().
Because method call is getting resolved at runtime by JVM that's why it is also known as Runtime Polymorphism and Dynamic Method Dispatch.
Difference Between Method Overloading and Method Overriding
For more details, you can read Everything About Method Overloading Vs Method Overriding.
Simple Definition - Method overloading deals with the notion of having two or more methods(functions) in the same class with the same name but different arguments.
While Method overriding means having two methods with the same arguments, but different implementation. One of them would exist in the Parent class (Base Class) while another will be in the derived class(Child Class).#Override annotation is required for this.
Check this :
Click here for a detailed example
Property Over-loading Overriding
Method Names -------------->must be Same----------------must be same
Arg Types------------------>must be Different(at least arg)
Method Signature
Return Type
Private,Static,Final
Access Modifier
try/Catch
Method Resolution
First, I want to discuss Run-time/Dynamic polymorphism and Compile-time/static polymorphism.
Compile-time/static polymorphism:- as its name suggests that it bind the function call to its appropriate Function at compile time. That means the compiler exactly know which function call associated to which function. Function overloading is an example of compile time polymorphism.
Run-time/Dynamic polymorphism:-In this type of polymorphism compiler don't know which functions call associates to which function until the run of the program. Eg. function overriding.
NOW, what are the function overriding and function overloading???
Function Overloading:- same function name but different function signature/parameter.
eg. Area(no. of parameter)
{ -------------
----------------
return area;}
area of square requires only one parameter
area of rectangle requires two parameters(Length and breadth)
function overriding:- alter the work of a function which is present in both the Superclass and Child class.
eg. name() in superclass prints "hello Rahul" but after overring in child class it prints "hello Akshit"
Tried to cover all differences
Overloading Overriding
Method Name Must be same Must be same
Argument Types Must be same Must be different
Return Type No restriction Must be same till 1.4V
but after 1.4V
co- variants
were introduced
private/static/final Can be overloaded Cannot be overridden
Access Modifiers No restriction Cannot reduce the scope
Throws keyword No restriction If child class method
throws a checked
exception the parent
class method must throw
the same or the
parent exception
Method Resolution Taken care by compiler Taken care by JVM based
based on reference types on run-time object
Known as Compile-Time Polymorphism, RunTime Polymorphism,
Static Polymorphism, or dynamic polymorphism,
early binding late binding.
I need to write a function that accepts an object , but I want to enforce in the function call (not after the function is called) that the object is an interface.
Meaning , I want to make sure this is an Interface at compile time , not on run time.
What do I mean?
interface ISomething {...}
class A implements ISomething { ... }
ISomething something = new A();
MyClass.register(something);
In this example , the passed object is an interface , and I want that the MyClass.register function to enforce the this requirment in it's declaration.
I don't know which interface I'm going to get , and there is no use defining another interface to be implemented by all other implementation , because I need the real interface.
To accept only objects that implement an interface as argument, use the interface as type, i.e.:
void acceptMaps(Map argument) {
}
can be called with objects implementing the Map interface, like HashMap but not with Strings for instance as they do not implement Map.
Is this what you meant with your question?
Edit in this example, objects implementing SortedMap which extends Map are accepted too, so in your case you could create a BaseInterface and extend that in the interfaces (like AcceptedInterface extends BaseInterface) you want to be accepted by your .register(BaseInterface arg) method.
You can't instantiate an interface so you would never be able to create one to send in. You can specify an interface in the parameters for the function and only objects which implement that interface can be passed in. But there is no way to require an interface be what is passed in because you can't create them.
I think you need to rethink what you're trying to accomplish.
You're making a distinction between the type of the object (in this case A) and the type of the reference to the object (in this case ISomething).
Sounds like you want to permit this code:
ISomething something = new A();
MyClass.register(something);
but forbid this code:
A something = new A();
MyClass.register(something);
I don't think you can achieve this with Java.
Let me see if I understand.
Do you want to check at compile time that the argument passed to a function is some interface? Any interface?
If that's the question, the answer is you can't.
I don't know which interface I'm going to get [...] I need the real interface.
You can't actually validate if you don't know which type to expect.
In Java you need to know the type to validate the parameter, the argument must be of the same type or a descendant, Java doesn't make distinctions on this regard at compile time, you can make it at runtime as Daff aswered.
You can ask the class of the object you get interfaces it implements during runtime.
If you can't already give the compiler the types of the interfaces you expect it has no way to predict what is going to be passed into your method so you will have to use runtime reflection.
There's no way to check at runtime, if the 'object is an interface' because an object can never ever be 'an interface', it only be an instance of a class that implements an interface.
And it's not possible to restrict a method signature to interface usage, say you'll allow type 'Animal' but not type 'Dog' which implements animal behavior. (I guess that's what you were looking for)
Taking your example - you want a compiler error for this implementation:
interface ISomething {...}
class A implements ISomething { ... }
ISomething something = new A();
MyClass.register(something);
A unwanted = (A) something;
MyClass.register(unwanted); // <- compilation error here
But practically spoken - I see no immediate reason. If you want to enforce programmers to use interfaces - user code inspection or quality check tools. If you want to restrict instantiation of an implementation, protect the constructor and use a factory to produce instances.
"The object is an interface" doesn't make sense. It seems like you want to enforce that the pointer passed into the function was declared with an interface type like
Interface_t x = new Class_which_implements_interface_t();
as opposed to
Class_which_implements_interface_t y = new Class_which_imlements_interface_t();
The only problem is that if you make a function like this:
void some_func(Interface_t z) {...}
And you call it with some_func(x); or some_func(y); the function is passing the reference by value, which means that inside of some_func, z is a copy of x or y which has been casted to an Interface_t pointer. There is no way to get information about what type the original pointer had. As long as it is able to be casted to an Interface_t it will compile and run.