why enum has constructor when interface cant have one? - java

It is known that Interface doesn't need constructor because all the data members of interface are public,static and final. Similarly enum also has all its constants as public static and final then how come it needs/had a constructor?

An interface cannot be instantiated, an enum can (and in fact will be, as each of its members is an instance of the enum itself).

Related

How to achieve functionality akin to an "abstract static" field

I've created an abstract class contains a method with an implementation. This method is called by subclasses to populate a list, which should be shared amongst all instances of each individual subclass (like an abstract static field which is different and static to each subclass). The issue is: abstract static fields do not exist, so how else might I be able to achieve this behaviour?
For context, the implemented method on the abstract class is for resolving classes from an unqualified name via the reflections8 package. This method calls an abstract method to get the packages to reflect, which just returns a String[] (as subclasses will want to search in different packages). This method then generates a Map<String, Class<?>> containing a mapping of the name of each reflected class to the Class, which is what I would like to share between instances of each specific subclass type (so that it doesn't have to reflect for the same subclass more than once). Ultimately, this method is called by the subclass in order to instantiate a class from its unqualified name.
Please forgive me if this is a rather strange way of doing things; I come from the land of iOS where we don't have package names attached to class names (so I can just call NSClassFromString("ClassName") and that's it).
EDIT: Check out this gist for the current implementation (and check out the comment for a usage example).
My thoughts: if you're wanting your subclasses to have their own respective static fields, it's best to just have those static fields declared in them rather than this abstract class.
From what I understand, your abstract class is really just a placeholder for this one implemented method. Do any of your subclasses override anything from the parent? If not, maybe it doesn't need to be an abstract class.
Plus, does your abstract class need any state? Because if not, you might be better off with this: change your abstract class to be a static class, and your implemented method be a static method, which accepts an "ClassName" argument. Then in your subclasses you can just directly call the method with your subclass' static fields using something akin to MyStaticClass. NSClassFromString(subclassStaticField);
There is no equivalent for abstract static for fields:
An instance field cannot be abstract. It really makes no sense. abstract means we are deferring some of the details to a subclass. But for an instance field there is nothing that it makes sense to defer.
A static field is not inherited anyway, so there is no way one could be used polymorphically. static fields with the same name in different classes are distinct variables.
You can (of course) use reflection to test if a field (static or instance) has been declared ... but that's not what abstract means in Java.
Solution:
If you want an instance field to exist in all of the subclasses of an abstract class, declare it as a regular field in the abstract class.
If you want a static field to exist in all subclasses, you have no choice but to explicitly declare it in each subclass. You won't be able to use it / them polymorphically.

Extend interface with defined fields?

I've got a question for you? As we all know, interface fields in Java are default public, static and final as well. How about extending interfaces?
For example if we have some interface with defined fields in it and we create another interface which extends interface with fields, we shouldn't be able to inherit fields, because they are literally static and also final. But we can! So could you explain it to me why?
interface interfaceWithFields{
String name = "Matthew";}
interface interfaceWithoutFields extends interfaceWithFields{}
And when we call standard output method, it will return Matthew:
System.out.println(interfaceWithoutFields.name); //no problem at all
Thanks in advance for responses. It's late at night and I might have confused something.
This is normal. Subclasses and subinterfaces in general inherit static members from their supertypes.*
9.2:
The interface inherits, from the interfaces it extends, all members of those interfaces, except for fields, classes, and interfaces that it hides; abstract or default methods that it overrides (§9.4.1); and static methods.
The wording there is kind of, umm wordy, but it says interfaces inherit static fields from superinterfaces unless they are not hidden. (Hiding is when you declare a variable with the same name.)
In practice, the compiler will just replace interfaceWithoutFields.name with interfaceWithFields.name. There is only one static variable name exists.
* (Except, weirdly, static methods are not inherited from superinterfaces.)
I'm not sure if this the technical answer, but in this case it works very similar to how a normal class would work. If you inherit from a Base class with a public, static, or final field, it will also be in the extended class. So at least in that sense it seems reasonable that interfaces would in a similar manner.

Java using overriden methods

I am a noob and I need some help.
So I have this abstract class with a private variable. I also have a method named getThing() to return that.
I have a class that extends that abstract class, and it too has a private variable and a method that overrides the original to get the value from the abstract class.
Well the only way to be able to access both values is by creating a second method in the subclass called getSuperThing, and using the super in that. Well I was just wondering out of curiosity if there was some easier way to do that and be able to access the abstract classes method by doing something like objectNae.super.getThing().
Thanks ;)
The variable is private and so can only be referenced by the containing (abstract) class. As you have stated, from a subclass, you can invoke the superclass method (rather than the overridden one).
If you want to make the variable accessible from the subclass directly (without requiring the accessor method), make it protected instead. Here is the documentation on Controlling Access to Members of a Class.
If I understand your question correctly, then you just shouldn't override the abstract class' method in the concrete subclass. No need to, unless you need the subclass to return a different value than that returned by the abstract class (and that would suggest poor design).
Rather, the abstract class' method will be accessible as a method of the subclass.
So, if you have:
public abstract class AbstractClass {
private int value = 3;
public int getValue() {
return value;
}
}
public class ConcreteClass extends AbstractClass {
}
then you should be able to do:
new ConcreteClass().getValue()
I don't think you have other ways than calling super.getThing() in the subclass's getThing() or getSuperThing() method. Abstract class must be subclassed before being used.

Why can't a Java enum be final?

public interface Proposal {
public static final enum STATUS {
NEW ,
START ,
CONTINUE ,
SENTTOCLIENT
};
}
Java does not allow an enum to be final inside an interface, but by default every data member inside an interface is public static final. Can anybody clarify this?
Java does not allow you to create a class that extends an enum type. Therefore, enums themselves are always final, so using the final keyword is superfluous.
Of course, in a sense, enums are not final because you can define an anonymous subclass for each field inside of the enum descriptor. But it wouldn't make much sense to use the final keyword to prevent those types of descriptions, because people would have to create these subclasses within the same .java file, and anybody with rights to do that could just as easily remove the final keyword. There's no risk of someone extending your enum in some other package.
An enum can't be final, because the compiler will generate subclasses for each enum entry that the programmer has explicitly defined an implementation for.
Moreover, an enum where no instances have their own class body is implicitly final, by JLS section 8.9.
Two things:
enums are final subclasses of java.lang.Enum
if an enum is a member of a class, it is implicitly static
No point in declaring enum final. Final for classes means that they can not be inherited. However, enums can not be inherited by default (that is they are final).
The final thing is valid only for variables. However you should think of the enums more like data types than variables.

Why can't constructors be final, static, or abstract?

Why can't constructors be final, static, or abstract in Java?
For instance, can you explain to me why this is not valid?
public class K {
abstract public K() {
// ...
}
}
When you set a method as final it means: "I don't want any class override it." But according to the Java Language Specification:
JLS 8.8 - "Constructor declarations are not members. They are never inherited and therefore are not subject to hiding or overriding."
When you set a method as abstract it means: "This method doesn't have a body and it should be implemented in a child class." But the constructor is called implicitly when the new keyword is used so it can't lack a body.
When you set a method as static it means: "This method belongs to the class, not a particular object." But the constructor is implicitly called to initialize an object, so there is no purpose in having a static constructor.
The question really is why you want constructor to be static or abstract or final.
Constructors aren't inherited so can't be overridden so whats the use
to have final constructor
Constructor is called automatically when an instance of the class is
created, it has access to instance fields of the class. What will be
the use of a static constructor.
Constructor can't be overridden so what will you do with an abstract
constructor.
A Java constructor is implicitly final, the static / non-static aspects of its semantics are implicit1, and it is meaningless for a Java constructor to be abstract.
This means that the final and static modifiers would be redundant, and the abstract keyword would have no meaning at all.
Naturally, the Java designers didn't see in any point in allowing redundant and/or meaningless access modifiers on constructors ... so these are not allowed by the Java grammar.
Aside: It is a shame that they didn't make the same design call for interface methods where the public and abstract modifiers are also redundant, but allowed anyway. Perhaps there is some (ancient) historical reason for this. But either way, it cannot be fixed without rendering (probably) millions of existing Java programs uncompilable.
1 - Actually, constructors have a mixture of static and non-static semantics. You can't "call" a constructor on an instance, and it they are not inherited, or overridable. This is similar to the way static methods work. On the other hand, the body of a constructor can refer to this, and call instance methods ... like an instance method. And then there is constructor chaining, which is unique to constructors. But the real point is that these semantics are fixed, and there is no point allowing a redundant and probably confusing static modifier.
public constructor: Objects can be created anywhere.
default constructor: Objects can be created only in the same package.
protected constructor: Objects can be created by classes outside the package only if it's a subclass.
private constructor: Object can only be created inside the class (e.g., when implementing a singleton).
The static, final and abstract keywords are not meaningful for a constructor because:
static members belong to a class, but the constructor is needed to create an object.
An abstract class is a partially implemented class, which contains abstract methods to be implemented in child class.
final restricts modification: variables become constant, methods can't be overridden, and classes can't be inherited.
Final: Because you can't overwrite/extend a constructor anyway. You can extend a class (to prevent that you make it final) or overwrite a method (to prevent that you make it final), but there is nothing like this for constructors.
Static: If you look at the execution a constructor is not static (it can access instance fields), if you look at the caller side it is (kind of) static (you call it without having an instance. Its hard to imagine a constructor being completely static or not static and without having a semantic separation between those two things it doesn't make sense to distinguish them with a modifier.
Abstract: Abstract makes only sense in the presence of overwriting/extension, so the same argument as for 'final' applies
No Constructors can NEVER be declared as final. Your compiler will always give an error of the type "modifier final not allowed"
Final, when applied to methods, means that the method cannot be overridden in a subclass.
Constructors are NOT ordinary methods. (different rules apply)
Additionally, Constructors are NEVER inherited. So there is NO SENSE in declaring it final.
Constructors are NOT ordinary methods. (different rules apply)
Additionally, Constructors are NEVER inherited. So there is NO SENSE in declaring it final.
No Constructors can NEVER be declared final. YOur compiler will always give an error of the type "modifer final not allowed"
Check the JLS Section 8.8.3 (The JLS & API docs should be some of your primary sources of information).
JLS section 8 mentions this.
Constructors (§8.8) are similar to methods, but cannot be invoked
directly by a method call; they are used to initialize new class
instances. Like methods, they may be overloaded (§8.8.8).
But constructors per say are not regular methods. They can't be compared as such.
why constructor can not be static and final are well defined in above answers.
Abstract: "Abstract" means no implementation . and it can only be implemented via inheritance. So when we extends some class, all of parent class members are inherited in sub-class(child class) except "Constructor". So, lets suppose, you some how manage to declare constructor "Abstract", than how can you give its implementation in sub class, when constructor does not get inherit in child-class?
that's why constructor can't be
abstract .
lets see first
final public K(){
*above the modifier final is restrict 'cause if it final then some situation where in some other class or same class only we will override it so thats not gonna happen here proximately not final
eg:
we want public void(int i,String name){
//this code not allowed
let static,, static itz all about class level but we create the object based constructor by using 'new' keyword so,,,,,, thatsall
abstract itz worst about here not at 'cause not have any abstract method or any declared method
Unfortunately in PHP the compiler does not raise any issue for both abstract and final constructor.
<?php
abstract class AbstractClass
{
public abstract function __construct();
}
class NormalClass
{
public final function __construct() {
echo "Final constructor in a normal class!";
}
}
In PHP static constructor is not allowed and will raise fatal exception.
Here in AbstractClass obviously a constructor either can be declared as abstract plus not implemented or it can be declared as something among (final, public, private, protected) plus a function body.
Some other related facts on PHP:
In PHP having multiple constructor __construct() is not possible.
In PHP a constructor __construct() can be declared as abstract, final, public, private and protected!
This code was tested and stood true for in PHP versions from 5.6 up to 7.4!

Categories