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.
Related
In the below code when I am having a class implementing two interfaces with same default method signature it ask me to override it. but in the overriden method why I have to use super keyWord to call the default method.
package practice;
interface interA{
public default void AImp(){
System.out.println("Calling Aimp from interA");
}
}
interface interB{
public default void AImp(){
System.out.println("Calling Aimp from interB");
}
}
public class Practice implements interA,interB {
public static void main(String[] args) {
Practice inter = new Practice();
inter.AImp();
}
#Override
public void AImp() {
interA.super.AImp();
}
}
I can do the same b using below code:
#Override
public void AImp() {
interA inter = new Practice();
inter.AImp();
}
Based on comment from #MalteHartwig.
Direct quote from Java tutorial:
If two or more independently defined default methods conflict, or a
default method conflicts with an abstract method, then the Java
compiler produces a compiler error. You must explicitly override the
supertype methods.
Consider the example about computer-controlled cars that can now fly.
You have two interfaces (OperateCar and FlyCar) that provide default
implementations for the same method, (startEngine):
public interface OperateCar {
// ...
default public int startEngine(EncryptedKey key) {
// Implementation
}
}
public interface FlyCar {
// ...
default public int startEngine(EncryptedKey key) {
// Implementation
}
}
A class that implements both OperateCar and FlyCar must override the
method startEngine. You could invoke any of the of the default
implementations with the super keyword.
public class FlyingCar implements OperateCar, FlyCar {
// ...
public int startEngine(EncryptedKey key) {
FlyCar.super.startEngine(key);
OperateCar.super.startEngine(key);
}
}
The name preceding super (in this example, FlyCar or OperateCar) must
refer to a direct superinterface that defines or inherits a default
for the invoked method. This form of method invocation is not
restricted to differentiating between multiple implemented interfaces
that contain default methods with the same signature. You can use the
super keyword to invoke a default method in both classes and
interfaces.
You didn't just override, you have implemented interfaces with same named methods. More exactly, you have implemented two interfaces and you have to resolve diamond problem no matter what code you want to run in AImpl. IDE required of you to override because of diamond hierarchy. Once you have provided code, interA.super is used as a way to navigate to desired code.
Practice class implements 2 interfaces.
Namely InterA and InterB.
The idiom used specifies which one of the 2 default methods you wish to call.
This is because the 2 methods have the same signature.
However when you override the signature on the Practice class like that:
package practice;
interface InterA {
public default void AImp() {
System.out.println("Calling Aimp from interA");
}
}
interface InterB {
public default void AImp() {
System.out.println("Calling Aimp from interB");
}
}
public class Practice implements InterA, InterB {
public static void main(String[] args) {
Practice inter = new Practice();
inter.AImp();
}
// #Override
// public void AImp() {
//
// interA.super.AImp();
// }
#Override
public void AImp() {
InterA inter = new Practice();
inter.AImp();
}
}
You do not get the same result.
You get:
Exception in thread "main" java.lang.StackOverflowError
at practice.Practice.AImp(Practice.java:35)
at practice.Practice.AImp(Practice.java:35)
at practice.Practice.AImp(Practice.java:35)
at practice.Practice.AImp(Practice.java:35)
at practice.Practice.AImp(Practice.java:35)
at practice.Practice.AImp(Practice.java:35)
at practice.Practice.AImp(Practice.java:35)
You reference an instance of Practice through the InterA interface, that forces the use of the implemented interface,which will instantiate again Practice and call AImp . This will recursively be repeated until a java.lang.StackOverflowError is thrown.
Actually, the use of word super is confusing here. As pointed out by #Basilevs, whenever there is a conflict of default methods from two interfaces implemented by a class, it will result into a compilation error (Fair Enough). To remove this error, the class must provide its implementation of that method, so compiler is not confused any more about which method it will invoke.
The next thing after resolving the compilation error is how to call the default implementations of the interface by-passing the implementation provided by the class itself. To do that, the method will be called with the name of the direct implemented superinterface that has defined the method.
In the example above, posted by #Ashraf Mulla, the call interB.super.AImp(); prints "Calling AImp from B" because that is what it is supposed to do as per Java specifications. Interface B is the direct interface which has the implementation for AImp method, so that will be executed.
To test further, one can also try having third interface which extends both interface A and interface B , which will need to provide its over-ridden implementation of AImp method to overcome compilation error. If a class, implements all the three interfaces (interface A, interface B and interface C extending A and B), then calling interA.super.Aimp, interB.super.Aimp will result in compilation error with the exact description to call with interC.super, that being the direct super interface having the method definition.
My code looks like this:
public abstract class BaseClass{
public void update() {
//...
}
public void somethingHappenedSoCallUpdate() {
update();
}
}
public class ExtendingClass extends BaseClass{
#Override
public void update() {
//...
}
}
There's an instance of ExtendingClass and at some point method somethingHappenedSoCallUpdate() is called. And I expect the method will call BaseClass.update() but ExtendingClass.update() is called. Can someone explain why?
And I expect the method will call BaseClass.update() but ExtendingClass.update() is called. Can someone explain why?
Because that's how Java is defined. By default, all non-private methods are virtual, which means that when you have overridden methods, the method that gets called on an instance is the instance's most-overridden version (ExtendingClass's, in your case), regardless of the type reference through which the method call is made. This is fundamental to polymorphism in modern OOP languages.
The compile-time type reference tells the compiler whether code has access to the method; the runtime type of the object tells the JVM which override of the method to call.
Let's take a simple example:
class Base {
public void method1() {
System.out.println("Base#method1");
}
}
class Derived extends Base {
#Override
public void method1() {
System.out.println("Derived#method1");
}
public void method2() {
System.out.println("Derived#method1");
}
}
// Usage:
Base b = new Derived();
b.method1(); // Calls Derived#method1, the most-overridden version the
// actual object has
b.method2(); // Fails to compile; Base doesn't define method2, so the
// code doesn't have access to call it when using a Base
// reference, even though the object does have the method
As #hyde said, Java methods are virtual, thats means that the VM decides at runtime which method to invoke. If you call somethingHappenedSoCallUpdate() on an instance that extends BaseClass then BaseClass.somethingHappenedSoCallUpdate() will be called, but since ExtendingClass is overriding BaseClass.update() it will class ExtendingClass.update() instead of BaseClass.update().
When extending a method you have to think of it like this:
whenever you extend a method you put it on a stack and when you invoke it, Java will look on this "stack" and invokes the topmost. That means if you have a BaseClass that has a update() method, this class can be extended by X classes not overriding the update() method but if the X+1 class does, Java will always call that method of X+1.
It's polymorphism:the right method is called at runtime depending on the real type of the object it's a dynamic binding.
Because you overrode update in subclass and since java methods are virtual overridden version is called.
Option #1
Override update, override somethingHappenedSoCallUpdate() method and use there super.update() instead of update().
Option #2
Make update private in superclass:
private void update()
You overrode the method so if you still want the code in the abstract class to run you need to implicitly call update() within the overridden method. So...
public class ExtendingClass extends BaseClass {
#Override
public void update() {
super.update(); // Call the base method.
}
}
Hope that helps :)
Getting error "The inherited method in Abs.show() cannot hide the public abstract method in iface" for the below written code.
package com.xprodev;
abstract class Abs {
void show(){
System.out.println("in show");
}
abstract public void print();
}
interface iface {
void show();
void print();
}
public class BasicAbs extends Abs implements iface {
public static void main(String[] args){
BasicAbs a = new BasicAbs();
a.show();
a.print();
}
#Override
public void print() {
System.out.println("in print");
}
}
I can resolve the error by making show in Abs as public. But I have few questions
Why the language support for this usage?
What can be achieved if this is allowed?
on calling a.print() only implementation of print will be called . Is that make sense to call this implementation is of method in Abs class or iface interface. Can we know that?
Why the language support for this usage?
It's not - that's why you get an error
What can be achieved if this is allowed?
Recall that BasicAbs is-a Abs.
If you allow "auto conversion" of package protected to public in case of a conflict with interface, you damage encapsulation, you can basically create some interface with a method for every method you want to expose from the base class (which might be someone else's class), and that's not a good idea.
on calling a.print() only implementation of print will be called . Is
that make sense to call this implementation is of method in Abs class
or iface interface. Can we know that?
Method m = BasicAbs.class.getMethod("print");
System.out.println(m.getDeclaringClass());
Will yield:
class BasicAbs
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.
Ok! I have same code written in Java and C# but the output is different!
class A
{
public void print()
{
Console.WriteLine("Class A");
}
}
class B : A
{
public void print()
{
Console.WriteLine("Class B");
}
}
class Program
{
static void Main(string[] args)
{
A a = new B();
a.print();
Console.Read();
}
}
Output: Class A. It is in C#.
But when same code was ran in Java, the output was Class B. Here is the Java Code:
class A
{
public void print()
{
System.out.println("Class A");
}
}
class B extends A
{
public void print()
{
System.out.println("Class B");
}
}
public class Program{
public static void main(String []args){
A a = new B();
a.print();
}
}
So, why this is showing different results? I do know that, in Java, all methods are virtual by default that's why Java outputs Class B.
Another thing is that, both languages claim that they are emerged or inspired by C++ then why they are showing different results while both have same base language(Say).
And what does this line A a = new B(); actually doing? Isn't a holding object of class B? If it is so, then why C# displays Class A and Java shows Class B?
NOTE This question was asked in interview with the same code provided above. And I answered with output Class B (with respect to Java) but he said Class A will be right output.
Thank you!
This is because in C# methods of derived classes hide, not override, methods of their base class. The methods that you would like to override need to be explicitly marked with the keyword virtual in the base, and with the keyword override in the derived classes.
In contrast, in Java all methods are virtual by default: simply specifying the same signature is sufficient for an override.
Here is how to make your C# program an equivalent of Java program:
class A
{
public virtual void print() // Add "virtual"
{
Console.WriteLine("Class A");
}
}
class B : A
{
public override void print()// Add "override"
{
Console.WriteLine("Class B");
}
}
After A a = new B(), variable a is holding object of B but the output is "Class A"! Shouldn't it call method of class B?
When you hide a method, rather than overriding it, your derived class keeps both methods - the one in the base class, and the one in the derived class. Both these methods remain accessible to the outside callers. They can decide which of the two methods to call by using an object of an appropriate static type. Here is an example:
B b = new B();
b.print(); // Prints "Class B"
((A)b).print(); // Prints "Class A"
Demo on ideone.
When you use virtual/override, you can access only one method from the outside - namely, the one in the derived class. The method in the base class can be accessed by methods of the derived class, but not by the outside users of the derived class.
In Java, non-static methods are virtual, whereas in C#, they are not. You will need to use the virtual and override keywords on your print method to get the same behaviour in c#.
Polymorphic behaviour in C#:
class A
{
public virtual void print()
{
Console.WriteLine("Class A");
}
}
class B : A
{
public override void print()
{
Console.WriteLine("Class B");
}
}
Edit
Getting back to your original C# code, you will get a compile time warning on B.print when you use the same method signature in both a subclass and its superclass, viz:
The keyword 'new' is required on 'print' because it hides method
'MyNamespace.A.print()'
This is a good indication that the method won't be called polymorphically / virtually. To avoid the warning (and retain your original C# behaviour), in B you would need to add new:
public new void print()