Java - Protected Modifier with Interface - java

public interface ICalculator {
public double multi(double a, double b);
public int add(int a, int b);
public int sub(int a, int b);
}
public class Calculator extends ICalculator {
protected int add(double a, double b) {
return a+b;
}
public double sub(int zahl1, int zahl2 ) {
return a*b;
}
}
why i can't use in the class Calculator a protected method ?
My answer is that "protected" is it useful in the same class and in the subclasses . Well couldn't i also think that a method in an implemented class from Interface is also inherited, like subclasses.

You cannot add more restriction to the method you override in the sub class.In the same way, you cannot add more restriction to the method you implement from an interface.
Now, since methods defined in an interface is by default - public (Yes, you don't need to write it explicitly), so you cannot make your method protected in implementing class.
The reason is straight, when you are working with polymorphism, you can instantiate your implementing class and store its reference in the interface type.
ICalculator calc = new Calculator(); //valid
calc.add(1, 2); // Compiler sees ICalculator method.
Now, when you invoke the add method using ICalculator reference, compiler only sees the method defined in ICalculator, and approves access accordingly. But at runtime, the actual method invoked is form Calculator class, and what happens now, if that method is actually invoked from a different package and non-subclass -- BOOOOOM, it crashes at runtime.
That is why it's not allowed.
Same concept applies when you are adding an extra checked exception. Compiler will again stop you. But yes, you can add an extra Unchecked Exceptionthough, because those are simply ignored by the Compiler.

From the Java Language Specification, §9.4:
Every method declaration in the body of an interface is implicitly public (§6.6).
Every method declaration in the body of an interface is implicitly abstract, so its body is always represented by a semicolon, not a block.
It is permitted, but discouraged as a matter of style, to redundantly specify the public and/or abstract modifier for a method declared in an interface.
And from the JLS, §8.4.8.3:
The access modifier (§6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method...
Put the rules from those two sections together and the conclusion is that any method that is part of an interface implementation must be public.

Interfaces in Java are usage-contract of a class for its clients. So all their methods are public, and you can not apply more restriction on overridden methods.

Related

Why use super call in a super class when it has no explicitly defined super class [duplicate]

This question already has answers here:
When do I use super()?
(11 answers)
Closed 7 years ago.
package Geometry;
public abstract class GeometryFigures{
protected double surfaces;
protected double perimeter;
public GeometryFigures(double surfaces, double perimeter) {
super(); //**<---Why use super call here?**
this.surfaces= surfaces;
this.perimeter= perimeter;
}
public double getSurfaces() {
return surfaces;
}
public double getPerimetre() {
return perimeter;
}
}
So basically everything is in the title. I want to know why i'd need to use the super() in a super class.
Thx for the help.
In this case super() refers to the constructor of Object, which is every class' Superclass.
You don't actually need to call it though, since by default a constructor always tries to call super() if no other superclass constructor is called.
I've seen some code generators add it automatically, my guess is that it is considered a best practice as an explicit reminder that super() will be called.
If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem.
according to docs.oracle
You don't have to, because it will be added implicitly for you by the compiler.
I think IDEs add it automatically for you because they generate code based on templates. This could be helpful if super constructor requires some arguments that could be extracted locally.
Imagine that you have this class:
public class A {
public A() {
// N lines of code
}
}
And then you have two child classes:
public class B extends A {
public B() {
// N lines of code
// M lines of specific code for class B
}
}
public class C extends A {
public C() {
// N lines of code
// P lines of specific code for class C
}
}
As you can note, since B and C classes inherit from A, you have to inherit the code of the constructor too. So, if you couldn't use super(), you would have to copy-paste all the code in every child class. And so on...
It also implies a certain level of abstraction when you extend some class, since the superclass may have certain code in its constructor, such as initializations.
In your example, there is no reason to use super(). Java will automatically make that call for you even if you don't explicitly write it.
So when do you need to call super()? Here's an example, using a subclass of your GeometryFigures class.
public class MyFigure extends GeometryFigures {
public MyFigure() {
super( 5.0, 42.0 );
}
// ...
}
Here you need a call to super() because there is no default (no argument) constructor in your class. Java will not supply a call to super() that has arguments (how could it? What parameters would it use?). So in this case you must supply a call, and specify which constructor and which parameters to use.

Hiding methods in subclass

I have a abstract superclass with some implemented methods.
Is it possible to hide methods from this superclass in an subclass inheriting from this superclass? I don't want to have some methods visible from the superclass in some of the subclasses. Last but not least, is it possible to change the number of arguments for a method in the subclass which has the same name in the superclass?
Let's say we have a method public void test(int a, int b) in the superclass but now I want a method public void test(int a) in the subclass which calls the superclass function and the method from the superclass not visible anymore.
Is it possible to hide methods from this superclass in an subclass inheriting from this superclass?
If you make the method private in the super class, it won't be visible in the subclass (or to any one else).
If you need the method in the base class to be public however, there is no way of hiding it in the subclass by for instance overriding it with a private implementation. (You can't "reduce visibility", i.e. go from for instance public or protected to private in a subclass.)
The best workaround is probably to override the method and throw for a runtime exception such as UnsupportedOperationException.
is it possible to change the number of arguments for a method in the subclass which has the same name in the superclass?
No, you can't change the signature. You can create another method with the same name and a different number of arguments but this would be a different (overloaded) method and the method in the base class would still be visible.
You can't completely hide a method from superclass, it's always possible to call, e.g.
MyBase o = new MyClass();
o.test(1, 2);
However, you can override the method in a specific way:
class MySuper {
public void test(int a, int b) {; }
}
class MyClass extends MySuper {
#Deprecated
#Override
public void test(int a, int b) {
throw new UnsupportedOperationException("Do not call this method, call test(int a) instead!");
}
public void test(int a) { ; }
}
No you cannot hide a public method in a child, for instance by making the method private there.
The reason is that having an instance of the child class, you may always cast it to the base class, and call the method there.
So this behaviour is logical. Either redesign the class hierarchy or create a new class if this is becoming a too ugly API.
You may however override the method and
/**
* Use <code>test(a)</code> instead.
* #param a.
* #param b.
*/
#Deprecated
#Override
public void test(int a, int b) {
throw new UnsupportedOperationException("Use test(int) instead.");
}
public void test(int a) { // Overloaded method
int b = ...;
super.test(a, b);
}
Overloading a method is possible: same name, different parameter types.
Java doesn't support reducing visibility.
There is a way to do something like this but it's complex:
You need to create an interface for the parent type. This interface doesn't need to have methods.
You create another, new type Delegate which implements the method public void test(int a, int b)
You delete the current parent type.
You create two new types which implement the interface. One delegates the call test(a,b) to Delegate and the other one creates a new method test(a) which eventually uses a Delegate instance.
So the type which implements the old code is never visible to the outside world (it could be a package private class).

what is the implicit declaration of interface methods in Java 8?

I was reading my old SCJP 6 book(author Kathy Sierra,Bert Bates) mentioned
All the interface methods are implicitly public and abstract by default
interface methods must not be static
For example, if we declare
interface Car
{
void bounce(); //no need of public abstract
void setBounceFactor(int b); //no need of public abstract
}
What the compiler sees
interface Car
{
public abstract void bounce();
public abstract void setBounceFactor(int b);
}
But from Java 8, interfaces can now define static methods. see this article everything-about-java-8
My question, what is the implicit declaration of interface methods in Java 8? Only public or nothing?
The rules for implicit modifiers do not change. Implicit modifiers are used when no other modifiers are specified. abstract is implied when neither static nor default has been specified. And all methods are always public whether implicit or explicit. Note that interface fields were always implicitly public static. This doesn’t change too.
But for the final words we should wait for the completion of Java 8.
Afaik it is something you can add and is added without changes to implementing classes.
For example. The List class will have a sort() method added. A sub class could have this method already but if every class needed this method it would break a lot of code and make having a default a bit useless.
I believe it is expected that the default method will be simple and call a static method or helper class to leave the interface uncluttered.
in short, default methods are public but not abstract.
btw interfaces have a method for static field initialisation.
what is the implicit declaration of interface methods in Java 8? Only
public or nothing?
Answer is: It is still public. private or protected are restricted. Look at following two examples
public interface A {
static void foo() {// Its ok. public will implicitly call.
System.out.println("A.foo");
}
private static void foo2() {// Compile time error
System.out.println("A.foo2");
}
}

What is "override-equivalence" and how is it related to #Override?

Reading the Javadoc for the #Override annotation, I came across the following rule:
If a method is annotated with this
annotation type compilers are required to generate an error message
unless at least one of the following conditions hold:
The method does override or implement a method declared in a supertype.
The method has a signature that is override-equivalent to that of any public method
declared in Object.
I'm clear on the first point, but I'm unsure about the second one.
What does it mean by "override-equivalent"? How are public methods of Object special in this respect? And why is this not covered under the first criterion?
Moreover, this is only true of the Java 7+ documentation. The Java 6 doc doesn't say anything about override-equivalence. Why the change?
Update:
After further consulting the JLS (Section 8.4.2), I found the following explanation of override-equivalence:
The signature of a method m1 is a subsignature of the signature of a method m2 if
either:
m2 has the same signature as m1, or
the signature of m1 is the same as the erasure (§4.6) of the signature of m2.
Two method signatures m1 and m2 are override-equivalent iff either m1 is a
subsignature of m2 or m2 is a subsignature of m1.
As far as I can tell, this answers the first question ("What does it mean?") and the third question ("Why doesn't the first condition cover this?").
If I understand correctly (please inform me if I don't!), there is only one case where two methods are override-equivalent and which doesn't fall under the first condition of the original question. This is the case when the erasure of the signature of the subclass method is the same as the signature of the superclass method, but not the other way around.
The second condition of the original question, then, would only come into play when we attempt to add type parameters when attempting to "override" a public method of the Object class. I tried the following simple example to test this, with an unused type parameter:
public class Foo {
#Override
public <T> boolean equals(Object obj) {
return true;
}
}
Of course, this class doesn't compile, because the method doesn't actually override the equals method and thus clashes with it. But I also still receive a compiler error for using the #Override annotation. Am I wrong in assuming that this example meets the second condition for #Override usage? Or is the compiler generating this error despite not being required to?
The reason for this is to allow you to use the #Override annotation in interfaces, which do not inherit from Object but implicitly declare all public methods from Object (see JLS section 9.2 interface members). You are thus allowed to declare an interface like:
interface Bar { #Override int hashCode(); }
However, you would not be allowed to declare the following interface:
interface Quux { #Override Object clone(); }
since the clone() method is not implicitly declared in an interface (it is not public).
This is described in JLS section 9.6.3.4 #Override (the Javadoc for #Override still refers to an old section number)
Your question is basically a design question and JLS explains its:
"The notion of subsignature is designed to express a relationship
between two methods whose signatures are not identical, but in which
one may override the other. Specifically, it allows a method whose
signature does not use generic types to override any generified
version of that method. This is important so that library designers
may freely generify methods independently of clients that define
subclasses or subinterfaces of the library."
Your code is not a valid example of this , see the below code it works:
public class SubSignatureTest extends SignatureTest {
#Override
public List test(Collection p) {
return null;
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
class SignatureTest {
public <T> List<T> test(Collection<T> t) {
return null;
}
}
Whole point is that signature of superclass and subclass should be same after erasure.
EDIT:
When we talk of override equivalence then parent class should have generic method and child class should have non generic method. Here is an example to explain this .Below code will not work because child class have generic method. For a moment lets assume that java allowed that then the call in main method will always fail :
class A{
public int compareTo(Object o){
return 0;
}
}
class B extends A implements Comparable<B>{
public int compareTo(B b){
return 0;
}
public static void main(String[] argv){
System.out.println(new B().compareTo(new Object()));
}
}
In class B method will be like this after compilation:
public int compareTo(Object x){
return compareTo((B)x);
}
Which means this is always error: new B().compareTo(new Object()) .
Therefore java will not allow child class to have generic method if parent class has non generic method. So you can't define override equivalence methods for object class.
Hope that clarifies.
I used the post http://lists.seas.upenn.edu/pipermail/types-list/2006/001091.html for reference, it has lot more details.

trying to understand implicit superinterfaces

Sorry to bring back the dead. But I still don't clearly understand what this section of specification states.
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 a method with the same signature, same
return type, and a compatible throws clause is explicitly declared by
the interface. It is a compile-time error if the interface explicitly
declares such a method m in the case where m is declared to be final
in Object.
Given
interface Testing
{
void test();
}
public class Test{
public static void main(String[] args) {
Testing t = new Testing(){
#Override
public void test(){
}
};
t.test();
t.toString();
}
}
Now as the spec states that the above will change to
interface Testing
{
void test();
String toString();
//other non-final methods of Object
}
public class Test{
public static void main(String[] args) {
Testing t = new Testing(){
#Override
public void test(){
}
};
t.test();
t.toString();
}
}
Also. please confirm if there is an hierarchy of interfaces then all of them get these abstract methods.
What it means is that every class extends Object (at some point in its class heirarchy). However, interfaces do not extend Object. This is to avoid the problems that arise from multiple inheirtance.
Since interfaces do not extend Object that would mean we were unable to use methods like toString if the type (not class) of the object we had access to was an interface. But we know those methods must be available since all classes at some point extend from Object. Therefore, to get around this problem all of Object's not final methods are implicitly declared in all interfaces that have no superinterfaces. These contracts of these methods are always satisfied since all classes must at some point extend from Object.
TL;DR -- it's a trick to make sure we can access the methods made available by Object when we have an instance of some class stored in variable that's type is an interface (eg. Serializable)
edit: To answer your question, You're slightly off. All non-final methods of Object are added to an interface (whether they are used or not) if that interface has no parent interface AND for each method to added: that there is no matching method is explicitly declared by the interface.
As long as there is no super interface to an interface it gets the implicit declaration of the Object class methods. As long as these methods are included in the interface. Every interface that either extends or implements this interface doesn't see much difference between the methods that are explicitly declared by this interface or it got implicitly. That point forward that interface is as good as declared them explicitly.

Categories