Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
overriding case:
class a{ public void m() {} }
class b extends a { #override public void m(){} }
hiding case :
class a { public static void m(){} }
class b extends a{ public static void m(){} }
is this one instance method hiding another?
interface i { void m(); }
interface j { void m(); }
class a implements i,j { void m(){} }
Can a instance method hide another instance method?
Static methods
In case of static methods you'd have to provide the class to the call anyways (they are class methods, not instance methods) and thus there'd be no hiding, e.g.
A.m(); //call static method on class A (btw, Java convention is that class names start with a capital case letter)
B.m();
Instance methods
Instance methods can't hide others, just override them, e.g. if B extends A, whenever you call m() on an instance of B, then the B version of m() would be called.
Interfaces
In case of interfaces you'd implement a method once even if it is declared in multiple interfaces.
As of Java 8 where there might be default implementations of interface methods and IIRC a concrete implementation would override the default implementation whereas two default implementations interfaces I and J would generate a compile time error (unless one interface is more specific, e.g. if J extended I.
class a { public static void m(){} }
class b { public static void m(){} }
These classes don't share a common ancestor, so one can't "hide" the other's method. In Java, same-name instance methods in subclasses always override the superclass's instance method, there is no hiding mechanism as there is in other languages (such as Pascal if I remember correctly). This is true even if the #Override annotation isn't made, the annotation just makes code more readable and helps against typos.
If you changed class b to extend class a, however, then it's static method m() would in fact hide the same name method in a.
This is what the Oracle docs have to say about this:
The distinction between hiding a static method and overriding an instance method has important implications:
The version of the overridden instance method that gets invoked is the one in the subclass.
The version of the hidden static method that gets invoked depends on whether it is invoked from the superclass or the subclass.
In the case of your interfaces:
interface i { void m(); }
interface j { void m(); }
class a implements i,j { void m(){} }
Interfaces don't provide any instance methods themselves, they are just a contract that the implementing class has to honor by implementing the methods declared in the interface. In your case, both your interfaces simply require the implementing classes (like class a) to implement a method public void m(). It's like promising both your wife and your daughter to take them out for ice cream on Saturday - the promise made to your daughter doesn't invalidate, hide or negate the same promise made to your wife. ;)
So in short: instance methods cannot be hidden in Java.
As a side note: Per the Java naming conventions, classes and interfaces should start with upper case letters.
If the method matches both signatures in i and j (which is here the case), it implements them both. If the signatures in the two interfaces don't differ enough to use overloading, they can not be combined into a single class.
There is no hiding/overriding when it comes to interfaces, only implementation.
For interfaces i and j, if a class implements both then that is fine, there is no violation of the interface.
For static methods, you can't hide it as you have to call it from the class i.e. a.m() and b.m(), hence it is not hidden.
Lastly for overriding methods, the method of the superclass isn't hidden, it is overridden.
Defining a Method with the Same Signature as a Superclass's Method
In a subclass, you can overload the methods inherited from the superclass. Such overloaded methods neither hide nor override the superclass instance methods—they are new methods, unique to the subclass.
In the case of #Override it's ok.
The interface case is different:
An interface define a contract it just say that the object marked as the interface can do something. Without defining how to do it. So you aren't hiding the method, but with the class that implements two interfaces you're defining that two action (with the same name) are executed in the same way.
Related
Case 1:
I have an Interface Inter.java:
interface Inter
{
void abcd();
}
A base class:
class Base
{
void abcd()
{
System.out.println("Base abcd");
}
}
A Derived class:
class Use extends Base implements Inter
{
void abcd() //intentionally not using public
{
System.out.println("Use abcd");
}
public static void main(String[] args)
{
Use u = new Use();
u.abcd();
}
}
Now I compile it:
gyan##ns:~/Desktop$ javac Inter.java Base.java Use.java
Use.java:3: error: abcd() in Use cannot implement abcd() in Inter
void abcd()
^
attempting to assign weaker access privileges; was public
1 error
gyan##ns:~/Desktop$
That means the overridden method abcd() in the class Use is from the implemented interface "Inter" and not from the base class "Base".
Case 2:
We have a file Test.java containing following codes:
interface Ab
{
void run();
}
class A extends Thread implements Ab
{
public void run()
{
System.out.println("class A");
}
public static void main(String[] args)
{
A a = new A();
Thread t = new Thread(a);
t.start();
System.out.println("main method");
}
}
When we execute it we got:
gyan##ns:~/Desktop$ java A
main method
class A
gyan##ns:~/Desktop$
Since t.start() executed the method run(), that means method run() of the class Thread got overridden. But in the case 1 method abcd() of the interface "Inter" got overridden.
In case 1: Whose method abcd() is overridden in class Use? Class Base or interface Inter? Error says we are overriding the abcd() of interface Inter. But in case 2: It seems that we are not overriding the method run of interface Ab. Because we can execute the run() method by calling t.start(). Which is only possible if we are overriding the run() of class Thread.
The method in your class overrides the base class method and implements the interface, at the same time.
Overriding a method is not exactly the same as implementing an interface :
Overriding a method from a superclass means you are replacing its implementation. If you are not providing an overriding method, the implementation from the superclass (which can be empty) will be used.
When implementing an interface method, you are providing code for a simple declaration (without any implementation). If you declare a not-abstract class as implementing an interface, but don't provide an implementation for every method of the interface, compilation fails. This is less true in Java 8, where you can optionnally provide a default implementation in interfaces, but in this case any implementation from a superclass would win.
Implementations and overrides of a method can always extend its visibility, but not decrease it. This means :
a package-private (default visibility), or protected method in a superclass can be made public in the subclass
but a public method in a superclass cannot be made package-private or protected in the subclass.
Methods in an interface are always public, even if the "public" modifier is not specified in the interface. Hence, their implementations must also be public => that's the error you get in your case 1
As a side note, in your case 2, you are using threads wrong. Do not subclass Thread. Instead, create a class implementing the Runnable or Callable interface, and submit it to a thread pool (see classes in java.util.concurrent, or for a quick test use java 8's ForkJoinPool.commonPool().submit(myTask).
Both. Method overriding depends on the name and signature of the method not where it is defined. If defined on more than one ancestor, it overrides both.
Note: If defined as public in one and protected in another, it'll become public.
In the Inter interface, void abcd(); is the definition of an abstract method. All abstract methods are inherently public.
From {Defining an Interface},
All abstract, default, and static methods in an interface are implicitly public, so you can omit the public modifier.
So, while Inter said that abcd() was public, the actual implementation in Use is saying that the implementation of abcd() is package-private, which is a weaker access privilege. This should address your comment "//intentionally not using public".
Traditionally, abcd() should also use the annotation #Override (although it is not a hard requirement).
In your second example, Thread class provides a concrete implementation of run(). Given that A#run() is public, you have satisfied the requirement imposed by interface Ab regarding access specifiers. Then, A#run() went on to override Thread#run() - which is exactly how we would expect inheritance to behave.
To summarize, we just saw the difference between extends (extending or overriding class methods) and implements (contract that the given class provides an implementation for all the methods states in the interface). {This answer} goes into more depth about this and is an excellent read.
Let me know if any part of this answer needs more clarity.
In Java a class can extend only one parent class but can implement multiple interfaces.
With
the introduction of default methods in Java 8 interface, there’s the possibility of a class inheriting more than one
method with the same signature by implementing 2 interfaces having the same default method
This can create diamond problem as in C++
Example in below code the output of
new C().hello(); is
This is Second
public interface First {
default void hello(){
System.out.println("This is First");
}
}
public interface Second extends First {
default void hello(){
System.out.println("This is Second");
}
}
public class MyClass implements First,Second {
public static void main(String[] args) {
new MyClass().hello();
}
}
What are the resolution rules that Java uses to resolve Diamond Problem?
A simple answer like who takes precedence and when will be great.
Following are the rules to follow when a class inherits a method with the same signature from multiple places (another class or interface):
Classes always win. A method declaration in the class or a superclass
takes priority over any default method declaration.
Otherwise, sub-interfaces win: the method with the same signature in the most specific defaultproviding
interface is selected. (for example in your case method from Second interface should run as Second extends First).
Finally, if the choice is still ambiguous, the class inheriting from multiple interfaces has to
explicitly select which default method implementation to use by overriding it and calling the
desired method explicitly.
There is the Oracle Tutorial that explains this pretty much in detail.
You have basically overridden your method from First interface and the most specific interface method is chosen.
Your snippet is no diamond problem as interface second extends interface first and overrides the method hello.
Without extending interface second the compiler throws an error
Duplicate default methods named hello with the parameters () and () are inherited from the types Second and First
Implementing two Interfaces that declare the same default Method leads to an compilation error:
MyClass inherits unrelated defaults for sayHi() from types InterfaceA and InterfaceB
So there's no Diamond-Problem ;)
To solve this you can override the Method in the implementing Class and either implement it there or defer to the correct Interface.
In your case it would look like that (in case you want to use the method of Interface First):
public class MyClass implements First,Second {
public void hello() {
First.super.hello();
}
}
Is it possible to have perform method overloading in different classes.
class Parent{
// Private method
private void method1(){
System.out.println("In private method of Parent class");
}
void method2(){
}
void method3(){
}
}
class Child extends Parent{
void method3(int i){
}
}
To perform overloading it is necessary to have two methods of same name and with different signature in the class. but in inheritance how does it work.
In inheritance is it true that copy of non private method is created in the child class?
In this example overloading is performed or not?
Overloading means methods with same name but different signature but not override equivalent for particular class. It's subject of class and not related to it's parent or child. Moreover, if parent has overloaded methods than child may or may not have the same behavior. Moreover, if any interface contains the overloaded signatures your class ultimately have the overloaded methods.
Note here that you have not overloaded method3(int i) with method() of parent, even more method of Child is not related to method of it's parent in your case. You can only override non-private and non-static methods of parent but you can not overload them, there is no meaning of overloading them.
Overriding - Redefining the methods in the Sub Class with out disturbing the signature. This is also called as Dynamic Binding, which will be decided during Runtime based upon the object being passed.
Overloading - Redefining the methods with in the same Class by changing the method signatures. This is also called as Static Binding, which will be decided during compile time.
Here, in your particular example, we SHOULD NOT say that the method3() is overloaded as we did not re-define method3() more than one time with in the same class.
I understand that in Java static methods are inherited just like instance methods, with the difference that when they are redeclared, the parent implementations are hidden rather than overridden. Fine, this makes sense. However, the Java tutorial notes that
Static methods in interfaces are never inherited.
Why? What's the difference between regular and interface static methods?
Let me clarify what I mean when I say static methods can be inherited:
class Animal {
public static void identify() {
System.out.println("This is an animal");
}
}
class Cat extends Animal {}
public static void main(String[] args) {
Animal.identify();
Cat.identify(); // This compiles, even though it is not redefined in Cat.
}
However,
interface Animal {
public static void identify() {
System.out.println("This is an animal");
}
}
class Cat implements Animal {}
public static void main(String[] args) {
Animal.identify();
Cat.identify(); // This does not compile, because interface static methods do not inherit. (Why?)
}
Here's my guess.
Since Cat can only extend one class if Cat extends Animal then Cat.identify has only one meaning. Cat can implement multiple interfaces each of which can have a static implementation. Therefore, the compiler would not know which one to choose?
However, as pointed out by the author,
Java already has this problem, with default methods. If two interfaces
declare default void identify(), which one is used? It's a compile
error, and you have to implement an overriding method (which could
just be Animal.super.identify()). So Java already resolves this
problem for default methods – why not for static methods?
If I was to guess again, I'd say that with default the implementation is part of Cat's vtable. With static it cannot be. The main function must bind to something. At compile time Cat.identify could be replaced with Animal.identify by the compiler but the code wouldn't match reality if Cat was recompiled but not the class that contains main.
Before Java 8, you couldn't define static methods in an interface. This is heavily discussed in this question. I'm going to refer to this answer (by user #JamesA.Rosen) as to why the Java designers probably didn't want static methods in an interface initially:
There are a few issues at play here. The first is the issue of
declaring a static method without defining it. This is the difference
between
public interface Foo {
public static int bar();
}
and
public interface Foo {
public static int bar() {
...
}
}
Java doesn't allow either, but it could allow the second. The first is
impossible for the reasons that Espo mentions: you don't know which
implementing class is the correct definition.
Java could allow the latter, as long as it treated Interfaces as
first-class Objects. Ruby's Modules, which are approximately
equivalent to Java's Interfaces, allow exactly that:
module Foo
def self.bar
...
end
end
However, since the release of Java 8, you can actually add default and static methods inside an interface.
I'm going to be quoting this source a lot here. This is the initial problem:
Java's interface language feature lets you declare interfaces with
abstract methods and provide implementations of those methods in the
classes that implement the interfaces. You are required to implement
each method, which is burdensome when there are many methods to
implement. Also, after publishing the interface you cannot add new
abstract methods to it without breaking source and binary
compatibility.
This was the solution Java 8 provided default:
Java 8 addresses these problems by evolving the interface to support
default and static methods. A default method is an instance method
defined in an interface whose method header begins with the default
keyword; it also provides a code body. Every class that implements the
interface inherits the interface's default methods and can override
them
And for static:
A static method is a method that's associated with the class in which
it's defined, rather than with any object created from that class.
Every instance of the class shares the static methods of the class.
Java 8 also lets static methods be defined in interfaces where they
can assist default methods.
When you implement an interface that contains a static method, the
static method is still part of the interface and not part of the
implementing class. For this reason, you cannot prefix the method with
the class name. Instead, you must prefix the method with the interface
name
Example:
interface X
{
static void foo()
{
System.out.println("foo");
}
}
class Y implements X
{
}
public class Z
{
public static void main(String[] args)
{
X.foo();
// Y.foo(); // won't compile
}
}
Expression Y.foo() will not compile because foo() is a static member
of interface X and not a static member of class Y.
Static methods in interfaces could create a diamond of death if they were being inherited. So, calling a static method from the appropriate interface is good enough compared to the risk of calling it from a concrete class that may implement multiple interfaces that contain static methods of the same name.
Why are static methods any different?
Static methods are just functions unrelated to the objects. Instead of placing them in utility abstract classes (like calling Collections.sort() ) we move those functions (static methods) to their appropriate interfaces. They could be bound to the inherited objects like the default methods do, but that is not their job.
Static methods provide functionality which is unrelated to the instances of the class.
Example:
interface Floatable {
default void float() {
// implementation
}
static boolean checkIfItCanFloat(Object fl) {
// some physics here
}
}
class Duck implements Floatable { }
So, the point is that a Duck may float but the function that checks if an Object really floats is not something that a Duck can do. It is an irrelevant functionallity that we could pass to our Floatable interface instead of having it sit inside some utility class.
Let's begin with some background ...
Java doesn't support multiple inheritance (the ability to extend more than one class). This is because multiple inheritance is prone to the deadly diamond of death (also known as the diamond problem) which the designers of Java chose to preempt.
If B and C override a method inherited from A, which method does D inherit?
A class can implement multiple interfaces because interface methods are contracted for overriding; if a class C implements two interfaces A and B that declare the same method, then the same method in C will be invoked by clients of either interface (A or B). The introduction of default methods for interfaces in Java 8 was made possible by forcing the implementer to override the default in case of ambiguity. This was an acceptable compromise since default methods are intended to be defensive (to be used if no other implementation is explicitly provided by an implementer). However, since the compiler can’t force you to override a static method (static methods inherently can't be overridden), the introduction of static methods for interfaces in Java came with one restriction: the static methods of an interface are not inherited.
The answer is that static methods belong to a class/interface and there is only one instance for static blocks. that's the reason you can't override any static method.
Even in classes, you may override but only the super class' static method gets executed.
Consider the following classes:
class A {
void print() {
System.out.println("A");
}
}
class B extends A implements C {
}
public interface C {
void print();
}
I get this error:
The inherited method A.print() cannot hide the public abstract method
in C
Now, I understand that print() must be public in order the eliminate the compilation error, but what's the reason behind this?
The answer is simple interface methods are always public or else just use composition instead of inheritance. Also to note that while overriding a method you can not narrow down the access level of the method.
The Oracle Docs says:
The access modifier public (§6.6) pertains to every kind of interface
declaration.
B#print can never be truly private, because anyone can call it via the interface:
B b = new B();
C c = b;
c.print();
Java doesn't let you pretend it's private when it is effectively public. (C++ does; different languages make different trade-offs.)
The method void print() in class A is implementation for the interface method declaration. Now , in the interface C this method is public ( every interface method is public by default ) and the rules of OOP ( Liskov principle in particular ) dictates that the visibility of this method's implementation in class A cannot be lower than that in its interface - hence it has to be public.
Short answer is because Java doesn't allow it. According to the Java Language Specification under 9.1.1. Interface Modifiers - JLS-9.1.1,
The access modifier public (§6.6) pertains to every kind of interface declaration.
The access modifiers protected and private pertain only to member interfaces within a directly enclosing class or enum declaration (§8.5.1).
So if you don't specify an access modifier in your non-member interface (like void print()) it is public and your class which implements that interface must provide a public void print().
Well, think it this way: if an interface defined private methods then these methods would only be called by the class implementing the interface, and that doesn't make much sense, since (in Java) an interface defines the contracts between classes. When a class follows an interface then the methods defined in the interface can be called in the implementation by external classes.
In your case, your class B is extending A while class A is not implementing the interface C. So, by extending A it inherits a method that has less access than the one defined in the interface, and that is not allowed.
If your class A had implemented the interface you would have seen the error "Cannot reduce the visibility of the inherited method from C"
All the methods in an interface are implicitly public. The names and return types of the methods(the ones B inherits from A and C) are same in your case but the visibility modifiers are different. And if you change the visibility modifier of an inherited method the compiler will complain because you cannot reduce the visibility of an inherited member.