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;
}
}
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)
Can have an abstract class implementing all of its methods-- with no abstract methods in it.
Eg.:
public abstract class someClass {
int a;
public someClass (int a) { this.a = a; }
public void m1 () { /* do something */ }
private void m2 () { /* do something else */ }
}
What's the advantage, if any, of having such an abstract class compared to having the same class as a concrete one instead?
One i can think of is that, when i declare it as abstract, it won't be instantiated.
however, i can have the same effect by making it concrete and its constructor(s) private.
TIA.
//==================
EDIT: One other use I can think of:
it may be extending another abstract class or implementing an interface without implementing that class's abstract methods-- although it is implementing all methods of its own. for whatever it' worth.
It has a conceptual meaning: this class has a behaviour which makes no sense on its own.
Granted, it's difficult to imagine such a scenario without well-defined extension points (i.e. abstract methods), but occasionally it will be a reasonably accurate model of your problem.
You can have something like this:
public abstract class ObjectWithId {
private final String id;
public ObjectWithId( String id ) {
this.id = id;
}
public final String getId() {
return id;
}
}
And then you can extend it to declare different types of objects that have ids. Here you have a fully specified and implemented behaviour but no restriction on any other behaviours subclasses may exhibit.
Note though that a much neater way to model the same thing is to use composition instead of inheritance.
public final class ObjectWithId<T> {
private final String id;
private final T ob;
public ObjectWithId( String id, T ob ) {
this.id = id;
this.ob = ob;
}
public String getId() {
return id;
}
public T getObject() {
return ob;
}
}
But before generics were introduced (up to Java version 1.4), this wouldn't have been as elegant and obviously better than the abstract class solution because you'd have had to trade in type safety.
you can declare to implement an interface and don't provide implementation and then each child implicitly gets interface extended
you prevent to create instance of this class
you in future provide common implementation to all children
As you pointed out, you can prevent the class from being instantiated by making it's constructor private. Othere than that, there is no benefit whatsoever. This is probably supported just to provide language completeness.
We generally use Abstraction concept with inheritance
Consider using abstract classes if any of these statements apply to
your situation:
You want to share code among several closely related classes.
To answer your question,
Why declare a class with concrete methods Abstract?
One possible reason is to support inheritance without actually creating objects
Assume you have two classes one Abstract and other Concrete
Abstract class : AbsClass
abstract class AbsClass {
int a = 5;
//Constructor
public AbsClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
and
Concrete class : ConcreteClass
class ConcreteClass {
int a = 10;
//Made the constructor Private to prevent from creating objects of this class
private ConcreteClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
The above two classes should function similarly (?) Until you try to Subclass them
class AbsImplementer extends AbsClass {
//Works fine
}
class ConcImplementer extends ConcreteClass {
//Compilation Error Implicit super constructor ConcreteClass() is not visible
}
The practical difference is that you can't create an instance of it. You would have to subclass it and create an instance of the subclass.
As to WHY you would want to do this, in practice ... I'm hard pressed to think of a good reason. You could say that the class is only meaningful if someone creates a subclass that implements some function. But then why not make that function abstract in the super-class?
I wouldn't rule out the possibility that someone might come up with some example where this makes sense, but I can't think of one. Just because it's possible to write a piece of code and that code compiles successfully doesn't mean that that it makes sense. I mean, I can write "total_price = item_price * zip_code + customer_height_in_cubits - 7.879", but that doesn't mean such a line of code would be meaningful.
Well assume that you don't care whether the methods of the abstract class are implemented or abstract, but by design it has to be abstract so that when someone extends it, they have to add more methods or override the existing ones or use as is. If they don't want to override the methods then the default behavior is already provided in that abstract class.
In this abstract class, the only criteria you enforce is - one simply cannot instantiate that class and they have to have their only version of class before using it.
So in general, abstract class with few or all methods being implemented, is much better than having an interface which has no methods implemented at all. This is based on the assumption that you are using it as a single inheritance.
Consider something similar to the NVI pattern (not sure what you'd call it in Java):
public abstract class A {
public final void doSomething() {
System.out.println("required");
doOptional();
}
protected void doOptional() {
System.out.println("optional");
}
}
public class B extends A {
#Override
protected void doOptional() {
System.out.println("overridden");
}
}
For your public API, you only expose a public final method which cannot be overridden. It performs some required work inside there and an optional method. When extending this class, you can only override doOptional().
Calling B.doSomething() will always print "required" before it proceeds.
Since doOptional() is not abstract, there's no purely code reason that class A needs to be abstract. But it might be desired for your particular project. For example, a base service that is always extended into specific sub-projects.
This can be useful for cases when the classes derived from the abstract base class must have some behaviour that is different from each other but that behaviour can not be abstracted as residing within a method that has the same signature for all the classes. Being unable to share a signature can occur if the different behaviour requires methods that are passed different primitive types. Because they use primitive types you can not use generics to express the similarity.
An abstract base class without any abstract methods is acting a bit like a marker interface, in that it is declaring that implementing classes must provide some behaviour without having that behaviour encapsulated within a new method with a signature that is the same for all implementations. You would use an abstract base class rather than a marker interface when the implementing classes have some behaviour in common, especially if the base class can implement it for the derived classes.
For example:
abstract class Sender {
protected final void beginMessage() {
...
}
protected final void endMessage() {
...
}
protected final void appendToMessage(int x) {
...
}
}
final class LongSender extends Sender {
public void send(int a, int b, int c) {
beginMessage();
appendToMessage(a);
appendToMessage(b);
appendToMessage(c);
endMessage();
}
}
final class ShortSender extends Sender {
public void send(int a) {
beginMessage();
appendToMessage(a);
endMessage();
}
}
It can be useful if you consider it an utility class.
Can have an abstract class implementing all of its methods-- with no abstract methods in it.
Eg.:
public abstract class someClass {
int a;
public someClass (int a) { this.a = a; }
public void m1 () { /* do something */ }
private void m2 () { /* do something else */ }
}
What's the advantage, if any, of having such an abstract class compared to having the same class as a concrete one instead?
One i can think of is that, when i declare it as abstract, it won't be instantiated.
however, i can have the same effect by making it concrete and its constructor(s) private.
TIA.
//==================
EDIT: One other use I can think of:
it may be extending another abstract class or implementing an interface without implementing that class's abstract methods-- although it is implementing all methods of its own. for whatever it' worth.
It has a conceptual meaning: this class has a behaviour which makes no sense on its own.
Granted, it's difficult to imagine such a scenario without well-defined extension points (i.e. abstract methods), but occasionally it will be a reasonably accurate model of your problem.
You can have something like this:
public abstract class ObjectWithId {
private final String id;
public ObjectWithId( String id ) {
this.id = id;
}
public final String getId() {
return id;
}
}
And then you can extend it to declare different types of objects that have ids. Here you have a fully specified and implemented behaviour but no restriction on any other behaviours subclasses may exhibit.
Note though that a much neater way to model the same thing is to use composition instead of inheritance.
public final class ObjectWithId<T> {
private final String id;
private final T ob;
public ObjectWithId( String id, T ob ) {
this.id = id;
this.ob = ob;
}
public String getId() {
return id;
}
public T getObject() {
return ob;
}
}
But before generics were introduced (up to Java version 1.4), this wouldn't have been as elegant and obviously better than the abstract class solution because you'd have had to trade in type safety.
you can declare to implement an interface and don't provide implementation and then each child implicitly gets interface extended
you prevent to create instance of this class
you in future provide common implementation to all children
As you pointed out, you can prevent the class from being instantiated by making it's constructor private. Othere than that, there is no benefit whatsoever. This is probably supported just to provide language completeness.
We generally use Abstraction concept with inheritance
Consider using abstract classes if any of these statements apply to
your situation:
You want to share code among several closely related classes.
To answer your question,
Why declare a class with concrete methods Abstract?
One possible reason is to support inheritance without actually creating objects
Assume you have two classes one Abstract and other Concrete
Abstract class : AbsClass
abstract class AbsClass {
int a = 5;
//Constructor
public AbsClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
and
Concrete class : ConcreteClass
class ConcreteClass {
int a = 10;
//Made the constructor Private to prevent from creating objects of this class
private ConcreteClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
The above two classes should function similarly (?) Until you try to Subclass them
class AbsImplementer extends AbsClass {
//Works fine
}
class ConcImplementer extends ConcreteClass {
//Compilation Error Implicit super constructor ConcreteClass() is not visible
}
The practical difference is that you can't create an instance of it. You would have to subclass it and create an instance of the subclass.
As to WHY you would want to do this, in practice ... I'm hard pressed to think of a good reason. You could say that the class is only meaningful if someone creates a subclass that implements some function. But then why not make that function abstract in the super-class?
I wouldn't rule out the possibility that someone might come up with some example where this makes sense, but I can't think of one. Just because it's possible to write a piece of code and that code compiles successfully doesn't mean that that it makes sense. I mean, I can write "total_price = item_price * zip_code + customer_height_in_cubits - 7.879", but that doesn't mean such a line of code would be meaningful.
Well assume that you don't care whether the methods of the abstract class are implemented or abstract, but by design it has to be abstract so that when someone extends it, they have to add more methods or override the existing ones or use as is. If they don't want to override the methods then the default behavior is already provided in that abstract class.
In this abstract class, the only criteria you enforce is - one simply cannot instantiate that class and they have to have their only version of class before using it.
So in general, abstract class with few or all methods being implemented, is much better than having an interface which has no methods implemented at all. This is based on the assumption that you are using it as a single inheritance.
Consider something similar to the NVI pattern (not sure what you'd call it in Java):
public abstract class A {
public final void doSomething() {
System.out.println("required");
doOptional();
}
protected void doOptional() {
System.out.println("optional");
}
}
public class B extends A {
#Override
protected void doOptional() {
System.out.println("overridden");
}
}
For your public API, you only expose a public final method which cannot be overridden. It performs some required work inside there and an optional method. When extending this class, you can only override doOptional().
Calling B.doSomething() will always print "required" before it proceeds.
Since doOptional() is not abstract, there's no purely code reason that class A needs to be abstract. But it might be desired for your particular project. For example, a base service that is always extended into specific sub-projects.
This can be useful for cases when the classes derived from the abstract base class must have some behaviour that is different from each other but that behaviour can not be abstracted as residing within a method that has the same signature for all the classes. Being unable to share a signature can occur if the different behaviour requires methods that are passed different primitive types. Because they use primitive types you can not use generics to express the similarity.
An abstract base class without any abstract methods is acting a bit like a marker interface, in that it is declaring that implementing classes must provide some behaviour without having that behaviour encapsulated within a new method with a signature that is the same for all implementations. You would use an abstract base class rather than a marker interface when the implementing classes have some behaviour in common, especially if the base class can implement it for the derived classes.
For example:
abstract class Sender {
protected final void beginMessage() {
...
}
protected final void endMessage() {
...
}
protected final void appendToMessage(int x) {
...
}
}
final class LongSender extends Sender {
public void send(int a, int b, int c) {
beginMessage();
appendToMessage(a);
appendToMessage(b);
appendToMessage(c);
endMessage();
}
}
final class ShortSender extends Sender {
public void send(int a) {
beginMessage();
appendToMessage(a);
endMessage();
}
}
It can be useful if you consider it an utility class.
my problem is:
I have a bunch of different classes all extending a base class (Identifiable).
I need to assign to some of the sub-class a certain value (securityLevel) which should be changeable and assigned to all member of the class (i.e.: it should be static).
I need to access the classes via the common ancestor.
How do I do this?
The first thing which came to mind is to have a dedicated interface (ISecurity) defining either the values or a static method to access them and let the actual classes either not to implements it and, if they do, to override the static field (or method to retrieve it).
However this is not possible for two reasons:
The current Java language does not allow static members in interfaces.
Even if it would allow it it would not be possible to #Override it.
How can I code around the problem?
The only way I found is:
add a non-static member (public Class getValueProvider()) to base class to retrieve the value returning null.
in the interested classes #Override the non-static method returning the value of a private static Class getValueProvider() implementing setters and getters for the wanted value.
use the retrieved class instance to obtain the requested value (or skip everything if the return is null).
This is very ugly and there's no way to enforce the correct implementation in sub-classes.
You could try a service/factory type of implementation. Or have some sort of class object that stores security (SecuritySettings) and send in the current Identifiable object to get security level
public class Identifiable { }
public class SampleUser extends Identifiable { }
public class ExampleUser extends Identifiable { }
public class UserService
{
public int SampleUserSecurity = 0;
//Or an array/dictionary structure
public int GetSecurityLevel(Identifiable user)
{
if(user instanceof SampleUser)
{
return SampleUserSecurity;
}
}
public SampleUser CreateSampleUser()
{
return new SampleUser();
}
public ExampleUser CreateExampleUser()
{
return new ExampleUser();
}
}
You could define Identifiable to be an abstract class. Additionally, you can define another abstract class that extends Identifiable and adheres to your restrictions, ie holds the static variable and whatever methods may be necessary.
I would try to avoid any static members. Static members in java are always clamsy (you cannot override just hide them, etc.)
I'm not sure if I understand your problem corret but I suggest you construct the objects with a context interface or something. The objects then cann access these context interface if they area allowed to return a value or have to return a special value.
The one creating all these objects can pass the same object and so control the behaviour. This object could then be held static (like a singelton)
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.