public class A
{
public static int i;
}
public class B extends A
{
public static void main(String[] args)
{
System.out.println("print i=" + B.i); // referred to A.i
}
}
My question here is how B.i is referred to the A.i?
If the static variable i is inherited why java allows to define another variable i in B class also?
A public or protected member of A is visible in all subclasses of A.
If the static variable i is inherited why java allows to define another variable i in B class also?
It's hard to speculate as to why. One possible reason is that this allows one to add members to a base class without breaking any derived classes that already happen to have a member with the same name.
Note that, if you define another i in B, it will shadow A.i, making it difficult to access the latter. I've seen people expecting this to behave polymorphically, but it doesn't (your case is slightly different anyway, since A.i is static).
i here is a static variable.A static variable,in layman terms,means a single copy being accessed by all classes.So,since your class B extends A,B has an access to the static variable of A.
If you define the variable locally,then the local value of the variable hides the parent class value.
there are 2 different things, scope and visibility. you can not redefine a variable in same scope twice (though you can redefine them in nested scopes).
But in case of inheritance, the subclass is out of scope of superclass, but yet has the visibility to that variable because of inheritance. So sub class allows you to define variable i again, though it will hide super class's variable. you wont be able to see its value. (unless used any getter from superclass)
Java allows you to change the specific variable value for the extended class.
This is because, static variables are shared between all objects of the same class.
It is a variable which belongs to the class and not to object(instance).
So, when extending the static variables of the parent class are not actually part of the extended class BUT are accessible (as long as they were not private).
Additionally, this can be used to do things such as:
using different STATIC CONSTANT for extended classes.
A use for this is to identify classes based on a STATIC integer as apposed to utilizing instanceof. This can be further combined with a switch to change behavior based on an objects type.
So, in the most basic example imagine we want to create a variable represent TYPE.
class A
{
public static final int NODE_TYPE = NODE_PERSON;
public static final int NODE_PERSON = 0;
public static final int NODE_CAR = 1;
}
class B extends Class A
{
public static int NODE_TYPE = NODE_CAR;
}
This has been used in many frameworks including Eclipse Abstract Syntax Trees:
http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.jdt.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fjdt%2Fcore%2Fdom%2FASTNode.html
You will see a list of STATIC INTEGERS which represent different Node Types.
Related
Consider the following snippet.
package breakoop;
public class BreakOOP {
public static class A{
private int a;
}
public static class B extends A{
public int f(){
return super.a;
}
}
public static void main(String[] args) {
B b = new B();
System.out.println(b.f());
}
}
The example only compiles if A and B are encapsulated within the BreakOOP class.
This seems to go against some of the fundamental concepts of OOP. Can someone explain why this compiles? What is the reasoning behind it?
Check this: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html. It says it increases encapsulation by allowing the static class to access private members of the top level class (sometimes you may need to do that). And a is private member of class A, which is in the scope of BreakOOP, which in turn makes it accessible inside class B.
The Java Language Specification states:
A private class member or constructor is accessible only within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
Since classes A and B are defined within the body of BreakOOP that rule applies and B can see private members of A.
As for the OOP concepts: since A and B are static inner classes they don't have the special life-cycle relation with BreakOOP that true inner classes have (i.e. you don't need an instance of BreakOOP to create a new instance of A or B but they still have a somewhat special relation in that they have access to private members. If they should not have that kind of relationship then they shouldn't be inner classes but true top level classes.
Hi I have two interface Ainterface and Binterface having same static final variable as 'i' which is declared as 10 and 20 respectively, I am implementing these two interfaces two my class InterfaceCheck where I am declaring same interface variable as static and final and initialized to 30. When I try to print the value of i in my class I am getting 30 as output. can some one explain me why I am able to reinitialize i to some other value even though its a final variable.
CODE
public interface Ainterface {
public final static int i=10;
}
public interface Binterface {
public static final int i=20;
}
public class InterfaceCheck implements Ainterface,Binterface {
public static final int i=30;
public static void main(String[] args) {
System.out.println(i);
}
}
>> output : 30
Class fields are always resolved on the static type of the reference.
In
public static void main(String[] args) {
System.out.println(i);
}
it implicitly does
System.out.println(InterfaceCheck.i);
so that is what you see.
Also, static fields are not inherited.
Static variables belong to the class itself (not to the instance) and these variables are not inherited by child class or implementing class.
Therefore:
public class InterfaceCheck implements Ainterface,Binterface {
public static final int i=30;
}
is not overriding i from those 2 interfaces. It is actually declaring a new independent static final variable.
Java has single inheritance because multiple inheritance has the problem of which members to pick when inherited classes collide on member names. But Java provides interfaces because that provides much of the power of multiple inheritance (additional behaviors) without the risk of name collision (but at the cost of choosing which methods so provide when method signature collision occurs).
Allowing class variables in interfaces is a relaxation of this rule, but was probably allowed because of where the member variable is located (one per class). As anubhava and Sotirios said they are not inherited, but declaring a new member, obscuring the inherited variable.
Your question concerns lexical scope. Since you have declared three 'public' variables which are class members, then you need to resolve scope. Since you have two inherited interfaces, do you really mean to define/set your own class variable, or to modify one or both of the inherited interface class variables?
I recommend you play around with the code to understand it fully whats going on, Very old thread here but all the same just wanted to add the following:
Comment out the static class "i" and when you run the code you will see java telling you "reference to i is ambiguous" ie, it does not know which one you want to call as it exists in both interfaces. Now un-comment the class static "i" and add two more printouts with the reference to both interfaces. As they are static this is allowed.
public static final int i=30;
public static void main(String[] args) {
System.out.println(i);
System.out.println(Ainterface.i);
System.out.println(Binterface.i);
}
30
10
20
Again if you remove the InterfaceCheck class static "i" constant and remove one of the interfaces it implements, say Binterface. You can reference the constant from Ainterface without its explicit reference as its the only static "i" created.
public class InterfaceCheck implements Ainterface {
public static void main(String[] args) {
System.out.println(i); //This will out Ainterface.i value of 10
//System.out.println(Ainterface.i);
//System.out.println(Binterface.i);
}
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)
I know that it's possible to do the following:
public class Indeed{
private class inner {
static final int try1 = 10;
}
}
Why? what's the point of allowing such a declaration?
Moreover it's still possible do the same thing in a local class:
public void doThing() {
class LocalClass {
static final int try1 = 10;
}
}
What's the use of a static final in those bits of code?
I am pretty sure I'll never use them, however I need to understand why they are used as I have an OCPJP7 exam to do.
Thanks in advance.
The purpose of a static variable is to be shared by all instances of the class. In both examples, you can have several instances of your private class / local class, so as specified they will share static variables among instances. What would be pointless is if you could only instantiate your class once.
JLS 8.1.3. : Inner Classes and Enclosing Instances
Inner classes may not declare static members, unless they are constant
variables (§4.12.4), or a compile-time error occurs.
The way I see it in the specs, is not having to answer the following dilemma:
static variables of an inner class are shared amongst all instances of the same outer class instance (but they can have different values from an outer class instance to another)
static variables of an inner class are shared amongst all existing instances in the VM, whatever their outer class instances.
Fortunately, when you declare it final, you know it will be the same for every instance, so you don't have to worry about this problem. That's why it is allowed.
For the question "why do static fields of inner classes have to be final":
This restriction is stated in the JLS as
Inner classes may not declare static members, unless they are constant
variables (§4.12.4), or a compile-time error occurs.
But this doesn't tell us why. Let's think about how we use inner classes. Imagine I write (try to) this.
public class A{
private class B{
static x;
}
public void updateX(int y){
B.x=y;
}
public void printX(){
System.out.println(x);
}
}
What happens when I do this
A one = new A();
A two = new A();
one.doStuff(1);
two.doStuff(2);
one.printX();
two.printX();
What should be printed? 1 then 2 or 2 twice? x is static so it should only exist in one place (in the Klass object of B) but as B is an inner class it should be specific to that instance of A. If we allowed static non final fields we would need to create an instance-specific Klass object per instance of the outer class. Which we don't want to have to do!
Static final fields are therefore allowed as they can live in the Klass object of B happily, and be shared across all instances of the outer class, because they can never change (being final).
I have an abstract class and 2 subclasses. There are 4 constants that relate to all the classes. I was going to place the finals in the abstract class but I understand a final variable is not inherited?
Would I have to define the constant in every class (seems inefficient)? Or just make the constant an instant variable (doesn't sound like a good idea)?
What are ways I can go about this?
The following would be available to all of your sub-classes if defined in the abstract class.
public static final Integer MYCONSTANT = 42;
or
static final Integer MYCONSTANT = 42;
or
protected static final Integer MYCONSTANT = 42;
The second one (package-private) is only available to classes within the same package. The third (protected) would be available to all sub-classes irrespective of their package.
Constants are inherited by childrens. You just have to make sure to have them protected or public so the children can access them.
abstract class A {
protected final static String FOO = "bar";
}
class B extends A {
somemethod() {
System.out.println("foo: " + FOO);
}
}
can be accessed from the class and all its children.
Yes they are. But as they are constant it should be final and static , static modifier make it there will be only one 'copy' and if this will be used only used in subclass only then u can use protected or if from other Classes too the must make it public.