public abstract class SuperClass {
public int x, y;
public static int z;
}
I want every subclass of SuperClass to have the static variable z. Naturally z will contain a different value for each subclass. I'm hoping to avoid defining z in every subclass, since it's going to be a functional dependancy of values x and y; Is this possible?
Unlike instance variables that are "one per instance", static variables are not "one per subclass" - they are "one per declaring class". In other words, subclasses of SuperClass share SuperClass.z, but they cannot "override" it on a class-by-class basis.
It does not mean that you cannot implement it yourself: on way to make your own per-subclass storage of integers is adding a static Map<Class,int> zs to SuperClass, with optional functions for accessing the data:
public abstract class SuperClass {
public int x, y;
private static Map<Class,Integer> zs = new HashMap<Class,Integer>();
protected static int getZ(Class c) {
Integer res = zs.get(c);
return res == null ? -1 : res.intValue();
}
protected static void setZ(Class c, int v) {
zs.put(c, v);
}
}
class SubClassOne extends SuperClass {
public int getZ() {
return SuperClass.getZ(SubClassOne.class);
}
}
class SubClassTwo extends SuperClass {
public int getZ() {
return SuperClass.getZ(SubClassTwo.class);
}
}
Probably the best way to do this is to have a z() method or similar in the abstract class, and override the method in the subclasses you want.
Example:
public abstract class SuperClass {
public int x, y;
protected int z() {
return 42; // protected so only subclasses can see it - change if required
}
}
public class SubClassOne extends SuperClass {
public void foo() {
// do something...
int z = z();
// something else...
}
}
public class SubClassTwo extends SuperClass {
#Override
protected int z() {
return 1;
}
// use z() accordingly
}
if i understand you correctly then do
public abstract class SuperClass {
public int x, y, z;
public SuperClass(int z) {
this.z = z;
}
}
then any class that extends this class inherits z;
Related
class AA{
int x;
protected AA(){init (1008);}
protected void init(int x)
{
this.x = x;
}
}
class BB extends AA{
public BB() {
init(super.x * 2);
}
public void init(int x)
{
super.x = x+1;
}
}
public class Main {
public static void main(String[] args) {
BB tst = new BB();
System.out.println(tst.x);
}
}
I know that this code will print 2019. Yet I do not understand why the superclass constructor,when called, will use the init method from de subclass instead the one from the superclass.
Yet I do not understand why the superclass constructor,when called, will use the init method from de subclass instead the one from the superclass.
Because that's the one associated with the object being constructed. this within the superclass constructor is a reference to the subclass object being constructed, so just like any other call to init using that reference, it uses the subclass's init.
This may help, note the lines with comments on the end — the comments say what those lines output:
class AA{
int x;
protected AA() {
System.out.println(this.getClass().getName()); // "BB"
System.out.println(this instanceof BB); // true
init(1008);
}
protected void init(int x)
{
this.x = x;
}
}
class BB extends AA{
public BB() {
init(super.x * 2);
}
public void init(int x)
{
super.x = x+1;
}
}
public class Main {
public static void main(String[] args) {
BB tst = new BB();
System.out.println(tst.x);
}
}
It's because subclasses can override methods that calling non-final, non-private methods from a constructor is usually best avoided.
public class MyTest {
public static void main(final String[] args) {
B b = new B();
b.print();
}
}
class A {
private final int x = 5;
protected int getX() {
return x;
}
public void print() {
System.out.println(getX());
}
}
class B extends A {
private final int x = 10;
#Override
protected int getX() {
return x;
}
}
In this example, I need to print subclass value in the parent class.
It is working fine. No issue.
Now it is printing 10.
But I do not want to define that property in the parent class A.
Because in this example this x datatype is very simple. So no issue.
But in real-time I want to use other datatype which may be another Class variable or List<something> which have huge data.
So ultimately I do not wish to store that value in Class A.
Because it is redundant data. It will slow down in my Hibernate thing.
Please let me know, how to achieve this without declaring variable in parent class. But I still need to use subclass variable in parent class.
make abstract your class A and the getX(); method.
public class Test {
public static void main(final String[] args) {
B b = new B();
b.print();
}
}
abstract class A {
protected abstract int getX();
public void print() {
System.out.println(getX());
}
}
class B extends A {
private final int x = 10;
#Override
protected int getX() {
return x;
}
}
and override the toString method in place of your print method
#Override
public String toString() {
return String.valueOf(getX());
}
the final code
public class Test {
public static void main(final String[] args) {
B b = new B();
System.out.println(b);
}
}
abstract class A {
protected abstract int getX();
#Override
public String toString() {
return String.valueOf(getX());
}
}
class B extends A {
private static final int X = 10;
#Override
protected int getX() {
return X;
}
}
you could also define as static your x variable
But as say Andrew Tobilko you can consider also to use an interface if A doesn't represent a stateful entity.
It's certainly the best solution for your case, mix the use of an interface and an abstract class
public class Test {
public static void main(final String[] args) {
B b = new B();
System.out.println(b);
}
}
interface MyInterface {
int getX();
}
abstract class A implements MyInterface{
#Override
public String toString() {
return String.valueOf(getX());
}
}
class B extends A {
private static final int X = 10;
#Override
public int getX() {
return X;
}
}
You need the getX within the parent class, but you don't have information enough to implement this method there.
You can declare this class as abstract and mark the method with abstract as well. Doing that, you are handing the responsibility of method implementation over its subclasses and preventing from parent field declaration.
If the A doesn't describe any state (only actions/methods), you should consider replacing it with an interface. At the current state, it is the case.
You could make the parent class abstract, eliminate the property in the parent class, make getX() abstract, and then leave print() as concrete. Then just use the concrete implementation of getX() in the child class.
I am having some trouble with inheritance (Student here). I need to be able to utilize 1 inherited private field for each subclass I make. Obviously subclasses cannot have access to inherited fields however when a new object is created that inherited private field is a part of that object. For my purposes though each subclass needs to have it's own specific value for that inherited field. My first attempt looks something like this:
Public class A {
private int x = 0;
public A(int n) {
x = n;
}
public int useX() {
return x;
}
}
Public class B Extends A {
int n = 1;
public B() {
super(n);
}
useX(); // Return 1?
}
Public class C Extends A {
int n = 2;
public B() {
super(n);
}
useX(); // Return 2?
}
However my professors tell me that I could also be using a setter method inside of my Super class to create that new field, and from there I am confused. Can anyone help point me in the right direction?
An ordinary Java Bean provides public accessors and mutators (aka getters and setters) for it's fields. However, you could provide a protected setter. Something like,
public class A {
private int x = 0;
public int getX() { // <-- the usual name.
return x;
}
protected void setX(int x) {
this.x = x;
}
}
Then your subclasses can invoke that setter
public class B extends A {
public B() {
super();
setX(1);
}
}
And then B.getX() (or B.useX() if you really prefer) will return 1.
At present, I've defined an empty interface X that is implemented by some other interfaces (just to identify them elsewhere).
All interfaces that implement X may provide as many public methods as they wish, but I want to enforce by design/by architecture, that all of them (note again that they are unknown to X) will return a type that is derived from the same abstract class Y.
Ist their any way I can do this in Java?
In the following example, X should enforce that only types derived from Y are returned by U and V.
public interface X {
// I'm empty at present.
}
public interface U extends X {
public A getA();
public B getB(String bIn);
}
public interface V extends X {
public C getC(Integer cIn);
public D getD(); // Compile should fail!
}
public class A extends Y {
}
public class B extends Y {
}
public class C extends Y {
}
public class D {
// D does *not* extend Y.
}
There is no way to enforce this with the java type system. You would therefore be left with:
reflection
customised static analysis
code reviews & developer education
I would stay away from reflection and static analysis. You haven't said what problem you are trying to solve with this, so it's difficult to give any alternate approaches.
I agree with #fge that this sounds like an XY problem, but I think you might be able to get something to work at compile-time.
You want to place a requirement on every method of a type, but Java only lets you specify that there exist some methods satisfying some requirements on a type, so you will have to refactor U and V.
In the set-up, I've made X specify that any implementors must provide a way to return a Y descendent. I've also specified that Y is an abstract class.
interface X {
Y getY();
}
abstract class Y {
}
Then, I looked at your interfaces U and V, and their methods U#getA(), U#getB(String), V#getC(Integer), V#getD(). All of these methods can be put in their own class.
class UA implements X {
public A getY() {
...
}
}
class UB implements X {
private final String s;
public UB(String s) {
this.s = s;
}
public B getY() {
...
}
}
class VC implements X {
private final Integer integer;
public VC(Integer integer) {
this.integer = integer;
}
public C getY() {
...
}
}
// COMPILE-TIME ERROR
class VD implements X {
public D getY() {
...
}
}
Now, anything that implements X must provide Y. The problem now is that UA, UB, VC, and VD can offer other methods. You've said you only want them to provide methods that return Y. To get around this, you can replace X with a final concrete class, which only provides a single constructor that you control.
Replace X with YFactory (everywhere in the code)
interface YFactory {
Y getY();
}
Now, specify X as a concrete class which only has one constructor:
final class X {
private final YFactory yFactory;
public X(YFactory yFactory) {
this.yFactory = yFactory;
}
public Y getY() {
return yFactory.getY();
}
}
All together:
final class X {
private final YFactory yFactory;
public X(YFactory yFactory) {
this.yFactory = yFactory;
}
public Y getY() {
return yFactory.getY();
}
}
abstract class Y {
}
interface YFactory {
Y getY();
}
class A extends Y {
}
class B extends Y {
}
class C extends Y {
}
class D {
// D does *not* extend Y.
}
class UA implements YFactory {
public A getY() {
return null;
}
}
class UB implements YFactory {
private final String s;
public UB(String s) {
this.s = s;
}
public B getY() {
return null;
}
}
class VC implements YFactory {
private final Integer integer;
public VC(Integer integer) {
this.integer = integer;
}
public C getY() {
return null;
}
}
class VD implements YFactory {
public D getY() {
return null;
}
}
Now you know that any X only has methods that return Y.
Im currently making a simple pluginable program. My problem is that I don't want to let plugin access all base-plugin fields/methods. For example:
public abstract class BasePlugin {
private int x; //Mysterious x
public abstract void update(); //update func that may need x, but can't change it
protected final int getX() {return x;} //x accessor
}
And that would work unless you realize that there is no way to set x.
What can I do? I want to make subclass (plugin) unable to change x, but let it read the value. Value should be accesible at least once when creating (that would be enough).
EDIT: Constructor works in most cases, but what if I have for example:
public abstract class BasePlugin {
private List<int> x; //Mysterious x
public abstract void update(); //update func that may need x, but can't change it
protected final List<int> getX() {return x;} //x accessor
public BasePlugin(List<int> y) {x = y;}
}
public class Plugin {
public Plugin(List<int> y)
{
super(y);
y.remove(0); //Will it work?
}
}
An abstract class is permitted to have a constructor, so you can create a parameterless constructor for BasePlugin:
public abstract class BasePlugin {
private int x; //Mysterious x
public BasePlugin() {
x = 42;
}
public abstract void update(); //update func that may need x, but can't change it
protected final int getX() {return x;} //x accessor
}
And now when a plugin is created, x is set to 42. You don't even need to make any code changes to the plugins to make them use this constructor.
To answer the edited question: If x is a List and you don't want the plugins to modify it, your constructor should be copying it and wrapping it in an unmodifiable list. Otherwise, any plugin can call getX().add(myObject).
public BasePlugin(List<int> y) {
List<int> temp = new ArrayList<int>();
Collections.copy(temp, y); // shallow copy of the list
this.x = Collections.unmodifiableList(temp);
}
Now if the plugin's constructor is
public Plugin(List<int> y)
{
super(y);
y.remove(0); //Will it work?
}
It will have no effect on the BasePlugin's list.
You can add a constructor to get your property initialized by the subclasses:
public abstract class BasePlugin {
private int x; //Mysterious x
public BasePlugin(int x) {
this.x = x;
}
public abstract void update(); //update func that may need x, but can't change it
protected final int getX() {return x;} //x accessor
}
You can use Constructor Injection.
public abstract class BasePlugin{
private int x;
public BasePlugin(int x){
this.x=x;
}
public abstract void update(); //update func that may need x, but can't change it
protected final int getX() {return x;} //x accessor
}
And in your childs
public class Plugin extends BasePlugin{
public Plugin(int x){
super(x);
}
}