Java static variable and inheritance - java

I have a base class where I have a static variable defined. From this post I know every class extending the base class will have the same copy of the class variable (static variable). Is there a way to make each extending class have it own "copy of the class variable"? I tried declaring the base class abstract but no luck.
public abstract class BaseBlah{
private static int number_of_threads;
}
public class Blah1 extends BaseBlah{
}
public class Blah2 extends BaseBlah{
}
My case is a little more complicated than the example since I want each extended class to abstract one common type of tasks executed in its dedicated thread pool which is the class variable in this case.

Every class will have it's own copy if you give it a copy of the field, but not automagically.
public abstract class BaseBlah{
private static int number_of_threads;
}
public class Blah1 extends BaseBlah{
private static int number_of_threads;
}
public class Blah2 extends BaseBlah{
private static int number_of_threads;
}
All the classes have their own copy of number_of_threads
Note: this would be called hiding if the fields were not private rather than inheritance.
`

Here's a semi-hacky way to do it, using a HashMap in the base class:
public abstract class BaseBlah{
private static HashMap<Class<? extends BaseBlah>, Integer> numThreadsMap = new HashMap<>();
protected int getNumThreads() {
Integer i = numThreadsMap.get(getClass());
return i != null ? i : 0;
}
protected void setNumThreads(int n) {
numThreadsMap.put(getClass(), n);
}
}
The upside of this is that there's nothing to remember for future implementing classes of BaseBlah. Whenever you create a new extending class it will "automatically" create a new "static" variable for the class.
The downside is that in order to use this approach you have to access it from a non static context (i.e. with an instance). It will behave as a static variable, but you can't treat it as such. static and class extension don't like each other (as this example proves) so fully integrating the two is always messy.

Related

Share a variable between functions in implementation of a interface

Consider an interface and its implementation,
interface A {
int a;
default void add() {
a = a+10;
}
public void sub();
}
class X implements A {
public sub() {
a = a-5;
}
}
I have to use the variable a in sub() function of class X. How can I do?
All variables declared inside interface are implicitly public static final variables(constants).
From the Java interface design FAQ by Philip Shaw:
Interface variables are static because Java interfaces cannot be instantiated in their own right; the value of the variable must be assigned in a static context in which no instance exists. The final modifier ensures the value assigned to the interface variable is a true constant that cannot be re-assigned by program code.
Since interface doesn't have a direct object, the only way to access them is by using a class/interface and hence that is why if interface variable exists, it should be static otherwise it wont be accessible at all to outside world. Now since it is static, it can hold only one value and any classes that implements it can change it and hence it will be all mess.
Hence if at all there is an interface variable, it will be implicitly static, final and obviously public!!!
The field a in the interface A always final and static and it isn't supposed to be modified in any way including reassigning it in an instance method.
Interfaces don't have the state. Abstract classes may.
abstract class A {
protected int a;
public void add() {
a += 10;
}
public abstract void sub();
}
final class X extends A {
public void sub() {
a -= 5;
}
}
I would use an abstract class instead of an interface. That way the variable can be modified by the extending class.
abstract class A{
int a=10;
void add(){
a=a+10;
}
public abstract void sub();
}
class X extends A{
public void sub(){
a=a-5;
}
}
Yes, We can use abstract class.
Since in interface variables declared are by default final.
Code with Interface
Code with Abstract Class

How to get attributes of a parent class in Java?

How do I get the attributes of Class A, a parent class (super class), to use it in Class C in Java.
For instance:
Class B extends A
Class C extends B
You need to declare the member protected:
public class A
{
protected int myInt = 5;
}
public class B extends A
{
}
public class C extends B
{
public int GetInt()
{
return myInt;
}
}
private member can be accessed only by the class itself, protected by the class and all the derived classes.
Typically it is best to keep attributes private, and access them via accessor (getter) and mutator (setter) methods from any other class, including derived classes. If the variable must or should be accessed directly from subclasses, which occasionally is desirable but not usually, then nearly always declare it protected.

when you extend a private class. are the public and protected members of class become private

when you extend a private class. Are the public and protected members of class become private. if not any explanation.
if you extend a nested private class, it wont change public/protected modifiers of the members. Here is an example :
public class Clazz {
private static class NestedClazz {
public int value = 123;
}
public static class NestedClazzExt extends NestedClazz {
}
}
you can now access the inherited member: value from outside
public static void main(String[] args) {
NestedClazzExt nestedClazz = new Clazz.NestedClazzExt();
System.out.println(nestedClazz.value);
}
you can create private class in side a class . We call it as Nested classe. Means a class inside a class. The Concept itself is saying that you can create private class in side another class. The private class will act like as data member to the outer class.
So, You can't extend the private class.
Based on your query I tried to prepare a simple class.
public class pvtClass {
private class As {
public String abc = "private attribute";
public void print(){
System.out.println("privateClass");
}
}
class Ab extends As{
public String ab = "extended attribute";
public void printAb(){
System.out.println("extended class");
print();
System.out.println(abc);
}
}
public static void main(String as[]){
Ab ab1 = (new pvtClass()).new Ab();
As as1 = (new pvtClass()).new As();
ab1.printAb();
as1.print();
System.out.println(as1.abc);
}
}
If you have a look at this class, I have a private class named "As" which has public attribute and public methods. I have another class named "Ab" which extends "As". I have written a main method to invoke the private attribute and methods.
below is the output for the code snippet:
extended class
privateClass
private attribute
privateClass
private attribute
There is a difference between the access of the members of a class and the access to the type itself.
public class C {
private class InnerP1 {
public void m() {
System.out.println("InnerP1.m()");
}
}
private class InnerP2 extends InnerP1 {
public void p() {
this.m();
System.out.println("InnerP2.p()");
}
}
public InnerP1 strange() {
return new InnerP2();
}
}
In this example, the interface I is visible from outside class C. The classes InnerP1 and InnerP2 are not visible from outside C. Jave itself makes not restrictions to the visibility of types you use in your public interface. The method strange() of class C returns a result of class InnerP1. Since outside of C we do not know anything about the class InnerP1 other than it is subtype of Object, the only thing we can do is use the result of strange() as an Object.
public class D {
public static void main(String[] args) {
C c = new C();
Object o = c.strange();
if(o.equals(c.strange())) {
System.out.println("Strange things are going on here!");
}
}
}
As #KnusperPudding pointed out already, the visiblity of public members is not changed, we might just not have enough knowledge of the type itself to access them.
Access to members cannot be restricted by sub-classing. When you mark a class as private then access via the class name is restricted i.e. to the same .java file, however once you have an instance of this class it can be accessed at least as easily as the super class.

Compiler errors when static abstract Inner class accesses outer class private fields java

I have a class with private fieds and also a static abstract inner class with the generic type extending the outer class type, that tries to access the outer class private fields but get's the following error:
- error: a has private access in Outer
- error: doSomething has private access in Outer
See code below:
public abstract class Outer extends SomeOuter
{
private Object a;
private void doSomething(){}
public static absract class Inner<T extends Outer> extends SomeOuter.SomeInner<T> {
public InnerMethod(T p) {
p.a; //error: a has private access in Outer
p.doSomething() //error: doSomething has private access in Outer
}
}
}
I'm compiling using jdk 1.7
Can anyone please tell me why am getting this error.
An Inner class can access private field of enclosing class and a static inner class can also access any private members of enclosing class .
The class itself isn't really "static"; there's no such thing as a static class. The
static modifier in this case says that the nested class is a static member of the outer
class. That means it can be accessed, as with other static members, without having
an instance of the outer class.
Since it is a static member , it is able to access outer class's private members , because within class private members are accessible.
eg.
class One
{
private int i=0;
class Two
{
void go()
{
System.out.println(new One().i); //accessible
}
}
}
class two
{
private int i=3;
static class one
{
void go()
{
System.out.println(new two().i); //accessible in static class
}
}
}
But here ,
Inner<T extends Outer> extends SomeOuter.SomeInner<T>
T is a class which extends Outer , doesn't mean it is inner.
That why it is giving error.
thats how private modifier works if you ever declare any method or variable as private than that things can not be accessed out side the class
A static embedded class is effectively an outer class. It can't access the private members of another class. See the accepted answer to:
Static nested class in Java, why?
Both the Object and the function you're trying to use are declared as private, which means they cannot be used outside the Object. If you want to use them in child classes as well, declare them as protected.
Changes the scope of the fields on the Outer class to protected so that classes extending Outer may access these fields.
public abstract class Outer extends SomeOuter
{
protected Object a;
protected void doSomething(){}
public static absract class Inner<T extends Outer> extends SomeOuter.SomeInner<T> {
public InnerMethod(T p) {
p.a; //error: a has private access in Outer
p.doSomething() //error: doSomething has private access in Outer
}
}
}
Thats what you have private modifier for. Though it is the inner class, it cannot access the private members of the outer class. So, declare it as protected, as you are extending the outer class to inner class

Static variables in an Abstract Class java

If I have an abstract class that has variables of the form
protected static final int blah;
protected static final int blah2;
And i have two classes that extend this abstract class, and set these variables to "static final int" values from a constants file in their constructors, will they clobber eachother's values? If I want to do such a thing, what would you recommend I do?
So, for example, if i have
impl1 class:
public impl1 extends absClass{
public impl1(){
this.blah = CONSTANTS.impl1_blah;
this.blah2 = CONSTANTS.impl1_blah2;
}
}
impl2 class:
public impl2 extends absClass{
public impl2(){
this.blah = CONSTANTS.impl2_blah;
this.blah2 = CONSTANTS.impl2_blah2;
}
}
Is this allowed? If not, what should I do?
this.blah = CONSTANTS.impl2_blah;
this.blah2 = CONSTANTS.impl2_blah;
this allowed?
This isn't allowed, since your blah variables are declared as final. You must initialize them during class initialization, either in their declaration or in a static initializer block.
Furthermore, these variables are static, and so accessing them using this won't work: the variables belong to the class and not an instance.
If not, what should I do?
Use non-final variables in the superclass, or use specific constants in the subclasses.
if classes extending that abstract class are supposed to give their own values for those variables then you should consider a couple of protected abstract methods instead.
static variables can't be overridden. Those will be associated with the classes where you have defined them.
static final variables must be initialized when the class that declares them is initialized. This is before any instances of the class (or any subclass) are created. Your code won't compile without some sort of initialization for blah and blah2—either an initialization expression:
protected static final int blah = 42;
protected static final int blah2 = 1;
or in a static initializer block:
protected static final int blah;
protected static final int blah2;
static {
blah = 42;
blah2 = 1;
}
In either case, subclasses have no say in what blah and blah2 get assigned.
It seems from your example code that you want constants that can vary on a per-instance basis. It doesn't make sense for them to be static. You can do something like this:
public AbsClass {
protected final int blah;
protected final int blah2;
protected AbsClass(int blah, int blah2) {
this.blah = blah;
this.blah2 = blah2;
}
. . .
}
public class Impl1 extends AbsClass {
public Impl1() {
super(CONSTANTS.impl1_blah, CONSTANTS.impl1_blah2);
}
}
public class Impl2 extends AbsClass {
public Impl1() {
super(CONSTANTS.impl2_blah, CONSTANTS.impl2_blah2);
}
}
Polymorphism in Java don't work with attributes. Use some protected abstract getMethods() instead.
First of all this is final+static which means nothing to do with OOP, If you make them not static then It makes sense to talk about OOP on it. If you do not do them as private and access them using getters/setters then you are breaking encapsulation.
And you are making it final, means it can be initialized only once. You will get exception when you try to change the value of final attr.

Categories