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.
Related
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.
In Java:
Scope of the function(s) declared in Interface is strictly public?
whereas,
Scope of the function(s) declared in Abstract class may be default, protected or public!!!
We know that both providing same problem description(As per my question above)
i.e. The Concrete class which inherit it have to define the function(s).
So, why different rules for both?
First of all, what you are talking about is "access" not "scope". It is important to get the terminology correct. Scope has a different meaning in Java.
An abstract class is really just like a normal class with normal implementation details (state variables and code) ... except that some of the implementation is left out; i.e. the abstract methods. So naturally you want the full repertoire of class language features.
A (pre-Java 8) interface is different1. Now there is no state and no code, just a "contract" that any implementing class must fulfill.
Now that doesn't completely address this question, but for the rest, I refer you to this Q&A - Protected in Interfaces - which asks why you can't use protected in an interface. As you can see, there isn't a single convincing answer. Rather there are multiple answers proposed, each of which could be valid to a lesser or greater extent. The only way to get the real answer(s) would be to ask James Gosling et al. Ultimately, it was a design choice made early in the life of the Java language.
So, why different rules for both?
Because the purpose of each of the two constructs is different.
1 - With Java 8, we can now declare default methods in an interface. In other words, there can be code in an interface now, albeit code that is common to all classes that implement the interface.
Interface defines the external, therefore public, interface of the class. When you use an interface you need not to know anything about how things are done internally.
An abstract class on the other just states what is missing to have a working implementation. For example, a pretty common pattern is:
abstract class x {
public void SomeTask() {
// ...
doSomeTask();
}
protected abstract void doSomeTask();
}
Because an interface is by definition a public interface. It makes no sense do define a non-public method(!) on an interface.
It makes perfect sense to define a private method on an abstract class.
An interface specifies how to interact with a type. Therefore, everything must be public, since it must all be accessible from outside the class implementing it.
An abstract class however, can contain protected, private or public because it can have implementation. It can call its own protected method, which will be implemented by a subclass.
Methods defined in abstract class can be executed in the same class. Interface doesn't execute any code, so there is no point in creating private of protected method. Interfaces are meant to be public, they are APIs to implementation.
This could be a useless question, Just out of my curiosity.
Why are we forced to add the keyword abstract in front of abstract method of abstract class, when we don't need to add
the keyword in the case of interface?
The possible answer could be:
As an abstract class may be a mix of concrete and abstract methods,
the 'abstract' keyword is used to identify which method(s) are abstract.
But
When we don't give any body to any methods, and use ; at the end of a declaration, then what could go wrong if it is considered as an abstract method automatically?
Why we are forced to add the keyword abstract in front of abstract method of abstract class, when we don't need to add the keyword in case of interface.
Within interfaces, all method definitions are implicitly abstract. You can provide the keyword, though, but there won't be any difference.
Within abstract classes, however, when you want to denote a method as abstract, you're required to type the abstract keyword. This actually makes the code more readable and easy to be understood.
Not all methods in an abstract class need be abstract. In fact, you can have an abstract class without any abstract methods.
On the other hand, all methods defined in an interface are implicitly public abstract, and so you can drop the qualifier.
You mention it explicitly so that anyone extending the class will know that he should implement those methods compulsorily and need not bother about the methods without the abstract keyword if he doesn't need to.
Two answers
Thats just the way language is designed
Abstract methods are meant to be overriden in child classes and that means some VM's can do various optimizations when they see abstract keyword
Btw. In java 4 there was actually abstract keyword in interfaces. Now it is considered as obsolete
Why can I not have a interface inside of a inner class? Why are they inherently static? Sorry if it's a stupid question, I've tried my best to google this again and again but I can't seem to wrap it around my head. As in why cannot I declare these in inner classes/local classes?
Also just as a confirmation, the reason we can have static final variables in a interface is because they do not specify the state or any of that sort of the implementation right? If we lose static and use just a final, we need a instance which makes no sense cause you can't instantiate a interface. Sorry, I really am confused, and I know I should just make another question but I think these two questions are somewhat related.
Think about what static means - "not related to a particular instance". So, as you point out, a static field of class Foo is a field that does not belong to any Foo instance, but rather belongs to the Foo class itself.
Now think about what an interface is - it's a contract, a list of methods that classes which implement it promise to provide. Another way of thinking about this is that an interface is a set of methods that is "not related to a particular class" - any class can implement it, as long as it provides those methods.
So, if an interface is not related to any particular class, clearly one could not be related to an instance of a class - right?
*Note, as #Owlstead points out, there are ways of defining interfaces within classes. But, for the purposes of wrapping your head around what an interface is (which seems to be what you're working on), I would ignore those possibilities for now as they distract from and possibly obscure the purpose of interfaces in general.
Why are they [interfaces] inherently static?
The difference between a static and a non-static nested class is in whether their instances have implicit references to enclosing instances (of the containing class), as well as to local variables from the containing scope. Before Java 8, there was no way for an interface to make use of such implicit references, because an interface could not initialize any non-static fields or provide any method implementations. (It still can't initialize non-static fields, though now it can provide default method implementations.) So before Java 8, there was no meaning in a non-static nested interface.
Also, from an implementation standpoint, these implicit references are implemented as an extra fields on the inner class, and they also require extra arguments to the inner-class constructor (in order to initialize these fields). Interfaces don't have fields, or constructors, so there's no way to implement this.
(Note: I don't usually recommend trying to understand language design decisions in terms of the implementation, because a single language feature can have many different correct implementations. But I think this is one case where understanding the implementation helps to understand the specification, hence the previous paragraph.)
Why can I not have a interface inside of a inner class?
Because interfaces are implicitly static: JLS §8.5.1:
A member interface is implicitly static (§9.1.1). It is permitted for the declaration of a member interface to redundantly specify the static modifier.
and you can't have non-final statics in an inner class.
Why are they implicitly static?
Because that's the way they designed it.
why cannot I declare these in inner classes/local classes?
Because they're implicitly static.
the reason we can have static final variables in a interface is because they do not specify the state or any of that sort of the implementation right?
Right.
If we lose static and use just a final, we need a instance
Right.
which makes no sense cause you can't instantiate a interface.
Yes you can. You can instantiate a class which implements the interface, or you can instantiate a method-local anonymous implementation of it. The real issue here is multiple inheritance of interfaces.
You cannot have an interface inside of an inner class because an inner class only exists within the context of an instance of an 'outer class'. Since this is the case, your interface would be de facto non-static.
You can, however have an interface inside of a nested class. See #owlstead answer. By placing the 'static' keyword on a the declaration of an 'inner class', it becomes a first class citizen, referencable from outside the outer class and (mostly) independent of the context of the outer class. Nested classes can be instantiated outside of the outer class; inner classes cannot.
After Java 16 release we can have static members inside Inner classes and static variables can be declared if they are final or effectively final. See this image
https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-8FD2B5E3-46C7-4C6C-8E8A-64AB49ABF855
Why do we create abstract classes even though all methods of that class are already defined?
If the answer is to stop the programmer from creating an object of that class, couldn't we achieve the same thing by using a private constructor?
A class being abstract only prevents that particular class from being instantiated. Child classes may still allow instantiation.
A class with no non-private constructors prevents subclassing as well as public instantiation.
From the above you can see that these two things serve two different purposes. A class may have either—or even both properties.
The idea of the Abstract class is a common base for a number of other classes..
Think of "Animals".. You cannot create something called 'Animal'..
You have Cats and Dogs and Rabbits that 'Are' animals.
You have a abstract class called "Animal" and then you have a class called Cat that extends Animal, or Dog that extends Animal... but you do not instantiate the class "Animal" directly as its only a common base.
The design pattern of creating a class as abstract even though all methods are defined is used when the abstract class has "do nothing" or exception-throwing implementations of the methods.
We can see this in action in the HttpServlet class, which has implementations for each of the web methods (doGet(), doPost(), doPut() and doDelete()) that throw a ServletException and which a subclass must override if they want a class that does something useful for a particular web method.
Any web methods not overridden with a working implementation will explode by default.
Abstract classes show that this class in itself will not be used independently and some other concrete classes should extend it to make complete sense.
While preventing using private constructor will inhabit subclassing.
Abstract classes with no abstract methods maybe a mistake of the developer.
In Abstract class you can define the constants which are common to many class
If you have a class which only contains static methods, the you can do it abstract, as there's no need of instantiating it. I can think about utility or helper classes at least.
Specifically regarding the use of abstract vs. hiding the constructor: The abstract keyword more clearly states the architectural intent of the programmer. It's better practice.
The fact that they've provided default implementations of all the methods is a separate question.