One more clarification about interfaces. Suppose, there is a class:
public interface Foo {
public static final String doSmth();
public static String doSmth2();
public final String doSmth3();
public String doSmth4();
public abstract String doSmth5();
}
1) Can I write abstract in method head in interfaces?
2) Can I omit words static, public, and final ?
There is no such interface. You'll get a compilererror. 1.) final methods can't be overriden. But you'll have to implement them because they are part of the interface. 2.) static methods can't be overriden. And due to this aren't allowed in interfaces (atleast not without methodbody). The accessmodifiers can be left out. But keep in mind, that methods without accessmodifier are packagelocal!!!
Methods are abstract by default in interfaces.
You can never omit static, public is just like in any other class, and you cannot have final methods in an interface.
And just so you know, the code of yours won't compile.
The variables in an interfaces are public static and final implicitely.
You can't create static methods in interfaces.
the final methods cannot be overrides, if a method in interface is final it cannot be override by any class so it has no sense of using final.
Related
Private interface methods are supported by Java 9.
This support allows non-abstract methods of an interface to share code between them. Private methods can be static or instance.
Can private methods of an interface be abstract or default?
May I ask for an example where "private static interface methods" are useful in terms of code?
No, the private methods in the interfaces are supposedly designed for clubbing in a piece of code that is internal to the interface implementation. Since these pertain to the implementation(consist of a body) and not the declaration it can neither be default and nor abstract when defined.
A private method is a static method or a non-default instance method that's declared with the private keyword. You cannot declare a default method to also be private because default methods are intended to be callable from the classes that implement their declaring interfaces.
The private static methods are useful in abstracting a common piece of code from static methods of an interface while defining its implementation.
Example of a private static method in an interface could be as follows. Consider an object, Question.java on StackOverflow defined as:
class Question {
int votes;
long created;
}
and an interface that proposes the sort by functionality as seen in the listed questions on StackOverflowTag :
public interface StackOverflowTag {
static List<Question> sortByNewest(List<Question> questions) {
return sortBy("NEWEST", questions);
}
static List<Question> sortByVotes(List<Question> questions) {
return sortBy("VOTE", questions);
}
//... other sortBy methods
private static List<Question> sortBy(String sortByType, List<Question> questions) {
if (sortByType.equals("VOTE")) {
// sort by votes
}
if (sortByType.equals("NEWEST")) {
// sort using the created timestamp
}
return questions;
}
}
Here the private static method sortBy of the interface internally implements the sorting based on the sortOrderType sharing the implementation with two public static methods of the interface which can be further consumed by a StackOverflowTagConsumer can simply access these interface static methods as :
public class StackOverFlowTagConsumer {
public static void main(String[] args) {
List<Question> currentQuestions = new ArrayList<>();
// if some action to sort by votes
displaySortedByVotes(currentQuestions);
// if another action to sort by newest
displaySortedByNewest(currentQuestions);
}
private static void displaySortedByVotes(List<Question> currentQuestions) {
System.out.println(StackOverflowTag.sortByVotes(currentQuestions));
}
private static void displaySortedByNewest(List<Question> currentQuestions) {
System.out.println(StackOverflowTag.sortByNewest(currentQuestions));
}
}
The default keyword for interface methods exist, because for interface methods, abstract is implicitly assumed if no other modifier contradicts it. Before Java 8, this applied to all interface methods, which were always considered abstract.
Since the presence of either, static or private, already implies that it cannot be abstract (which applies to ordinary classes as well), there is no need to add a default modifier and consequently, Java rules out this combination. And there is no point in asking for this combination either, as default merely implies that the method is not abstract, technically, so adding it to a method which is already not abstract wouldn’t change anything.
On the other hand, since the only methods needing a default keyword for declaring that they are not abstract, are public instance methods, the default keyword only applies to overridable methods, which conveniently matches the literal meaning of the word “default”.
private methods are useful to provide common operations for the public non-abstract methods of an interface when these common operations are not supposed to be called from the outside of the interface directly, much like private methods in ordinary classes, further, they exist in Java 8 already on the byte code level, as default and static methods may contain lambda expressions which are compiled into synthetic private methods, so there was no technical reason to deny that feature to the Java programming language.
No, these three combinations are mutually exclusive. Interface methods cannot be at the same time:
Default and abstract (because default means the opposite of abstract)
Default and private (because you cannot override a private method)
Abstract and private (because you cannot override a private method)
I'm trying to implement interface like this :
public interface Human{
void talk();
}
public class Ame implements Human{
public static void talk(){
System.out.println("Speak English");
}
}
public class Chin implements Human{
public static void talk(){
System.out.println("Speak Chinese");
}
}
public class test {
public static void main(String[] args){
Chin c = new Chin();
c.talk();
Ame a = new Ame();
a.talk();
}
}
But it shows errors :Ame and Chin talk() cannot implement Human talk().
Methods is overridden as static .
Please tell me why this heppened and how to fix this error.
Static methods are part of Class and not Objects. Overriding is concept of polymorphism, ie, a method associated with an instance can have multiple behaviour.
Static methods are not associated with instance and polymorphism cannot be applied.
When you declare a method as static, it belongs to the class as a whole and not a specific instance. The methods of an interface cannot be static in Java. When you implement an interface, you are expected to provide an instance method for the abstract methods of the interface. When you use a static method, your static method tries to hide the instance method of the same name. But this would violate the rules to be followed while implementing an interface. Thus we cannot make the interface methods as static in the implementing class.
You cannot reference a non-static interface from a static method this way. In essence, a static method is one that can be accessed directly without recreating a local duplicate object, but its values cannot be modified in the same way. Really, the solution to this problem is quite simple. Remove the static modifier from the overriding talk() methods
I found such an usage of protected modifier while searching for a solution for my other question: Ignoring case in strings with unitils ReflectionComparator
In the org.unitils.reflectionassert.ReflectionComparatorFactory class there is a method with the signature:
protected static List<Comparator> getComparatorChain(Set<ReflectionComparatorMode> modes)
But this is only a particular case.
After all we can always extend such any non-final class and "override" it's static protected method with the new public modifier. Say, we have a class A:
public class A {
protected static void test() {
// do some stuff
}
}
and want to use it in another package:
public class UseA {
private static class MyA extends A {
public static void test() {
A.test();
}
}
void useA() {
// A.test(); compile error, sure
MyA.test();
}
}
I concentrate my question on a general situation when some static method was declared as protected. I'm not asking about non-static fields or methods, because in some cases class can have a private constructor or a very complicated constructor with lots special params. But what is the purpose of such "hiding" static methods if entire class isn't final? Is such usage an OOP mistake or just a very weak "protection"?
But what is the purpose of such "hiding" static methods if entire class isn't final?
A protected static method would allow you to provide "utility" type functionality to derived classes, without exposing them in the public API where they might not make sense on their own.
I don't know the implementation of the getComparatorChain method you reference, but I imagine it's such a method. It would be marked static if it's not tied to any specific instance, and marked protected so as not to be a part of the public API, but also to allow derived classes to re-use the utility method in it's own implementation.
Overriding a static method reference means hiding it's implementation. See: Java Documentation's Overriding and Hiding Methods
Static Methods
If a subclass defines a static method with the same signature as a static method in the superclass, then the method in the subclass hides the one in the superclass.
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.
This question already has answers here:
What is the use of interface constants?
(13 answers)
Closed 9 years ago.
Recently I saw in somebody's code that he implements his final class variable fields inside an interface ex:
public interface commentSchema{
static final String DB_TABLE_NAME = "comment";
...
}
& he had implemented a class which does need these variables something like this:
public class DbComment implements commentSchema {
// use the DB_TABLE_NAME value here ...
...
}
as you know If someone make an instance of DbComment class because of inheritance aspect, he's gonna be able to access the DB_TABLE_NAME which is not proper because we want to use those values only inside DbComment methods.
now I have several questions:
1) is this implementation proper & ok ?
2) if It's not, how we have to declare these variables outside of DbComment class & make this class be the only class who does see these values. (we don't want to use abstract class coz a class can only extends one other class in java)
3) why we do need to use static for values & methods which exist inside an interface ? (when we implements certain interface for a specific class why do we need to make it static to be seen everywhere?)
4) is there any specification that exactly determine kinds of different declarations for java methods, classes, enums, etc ?
1) is this implementation proper & ok ?
Yes, will work just fine.
2) if It's not how I'm gonna declare these variable outside of DbComment class & make this class be the only class who does see DB_TABLE_NAME value. (I don't want to use abstract class coz a class can only extends one other class in java)
No need as the implementation used works as expected.
3) why we do need to use static for values & methods which exist inside an interface ? (when we implements certain interface for a specific class why do we need to make it static to be seen everywhere?)
You can't make methods in interfaces final or static. The only qualifiers allowed for methods are public and abstract which have, by the way, no effect at all.
For fields, static exists, but also has no effect. All fields declared in a interface will be accessible statically by the implementors and are considered constants.
4) is there any specification that exactly determine kinds of different declarations for java methods, classes, enums, etc ?
The official spec has a chapter on Names and Declaration.
By default, any field declared inside an interface is marked as public static final even if the programmer doesn't do it. This means, any field in the interface will be constant and impossible to modify.
If you don't want that functionality (whatever reasons you could have) then it would be better to have an abstract class instead and mark the field as protected static final.
public abstract class CommentSchema{
protected static final String DB_TABLE_NAME = "comment";
}
Still, if you want to base your design to interfaces, then you can have the interface without this field, then an abstract class that implements this interface and adds the field. By doing this, every class that extends the abstract class will implement the interface and have access to the field:
public interface CommentSchema {
foo();
}
public abstract class CommentSchemaAbstractImpl implements CommentSchema {
protected static final String DB_TABLE_NAME = "comment";
}
public class CommentSchemaRealImpl extends CommentSchemaAbstractImpl {
#Override
public void foo() {
//do something...
baz(DB_TABLE_NAME);
}
private void baz(String s) {
//fancy code here...
}
}
At last, you can forget about all this and create an enum to handle your constants.
public enum TableName {
COMMENT("comment");
private String tableName;
private TableName(String tableName) {
this.tableName = tableName;
}
}
Can I create a abstract class like below..?
abstract class A{
private final String foo;
private final String too;
public A(final String foo, final String too) {
this.foo= foo;
this.too= too;
}
public String getfoo(){
return foo;
}
public String gettoo(){
return too;
}
}
Short: yes.
Long(er): an abstract class is just a class that can't be instantiated as is, since parts might still be missing. Thus i can have private fields. Just note that subclasses don't have access to them, except via the getters/setters.
Your code is correct.
Note: good practice in abstract classes is protected constructor, beacuse class itself cannot be instantiated and the inheriting classes must have to call super(...) constructor.
Yes you can.
Consider the possibility to make them protected instead of private to allow your subclasses i.e. the ones extending this class, to have direct access to the fields..
Yes of course possible.But it is not a good practice because you cant create one object of this class.Main point is that you also dont require this type of class because you have not define any abstract functions inside it. But as per your question you can definitely create this type of abstract class.