How to access similar fields of superclass in multilevel inheritance - java

If base class and derived class have same field name, then we use super keyword to access base class field. But in case of multilevel inheritance and there also in every class has same field name, how to access field name of super class in child class.
class GrandParent {
String name;
}
class Parent extends GrandParent {
String name;
}
class Child extends Parent {
String name;
//now here, how to access GrandParent name field
}

There is no multiple inheritance here. Your snippet demonstrates field hiding.
Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different. Within the subclass, the field in the superclass cannot be referenced by its simple name. Instead, the field must be accessed through super.
super allows you to see members only on one level down (=members of the direct parent). Chains like super.super are considered syntactically invalid.
But there are at least two ways to achieve what you want:
(GrandParent)this).name - upcasting to GrandParent
GrandParent.class.getDeclaredField("name").get(this) - extraction by reflection

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.

Java subclass calling superclass

I'm having a little trouble with inheritance. What i have done is made a superclass as some of the attributes in the subclasses were identical.
I am trying to reference the superclass, I tried putting super(name); above the line name = replacementName; it will not compile saying name has private access in the Superclass 'person'. I know that it won't access a private field but how can I get the name from the superclass in a subclass method?
Here is the method.
public void changeName(String replacementName){
name = replacementName;
}
Help appreciated.
You have several options :
1 - In your super class, use private declaration for the name attribute and add public (or protected) getters/setters. Then you can modify your super class field from your child class using the setter method.
2 - In your super class, use protected declaration for your name field. Then you can access it directly from your child class.
...

If two classes in java have generalization relationship, can the child only inherite some, not all, mehods of the parent class?

For example:
I have customer class which has two child classes, which are guest class or signed-up users class. Customer class has username as an instance variable. Does guest class also have username as an instance variable? How about methods of customer class?
Inheritance in Java is always complete, in the sense that all attributes and methods will exist in the child class. Those that were declared in the "super" class as private will not be visible in a subclass, although they will still be there.
If you're thinking about some sort of partial inheritance, the best thing you can do is rethink your class model: create a different base class that can be applied to all particular cases (so that if you have a username attribute in the Customer class, you must be sure that all customers will have one). If you don't want Guest objects to have that attribute, simply remove it from Customer and declare it in your SignedUpCustomer class. Java interfaces may also be useful in other occasions.
The Guest class and SignedUpUsers class will inherit all the class members (methods and variables) from the Customer class that do not have their access level marked as 'private' or default (no access level specified).
So in your example, if username variable has access level public or protected, then it will be inherited. The same goes for all your methods.
String username; // will not be inherited
private String username; // will not be inherited
protected String username; // will be inherited
public String username; // will be inherited

How to put a static variable in a parent Object that is different between different children in Java

Conider I have a Class called Entity that has 3 children :
ClientEntity, EmployeeEntity and ProductEntity
I want to have a static attribute _nextId (that gives the new id for a new record)
_nextId has a different value in each entity, but its a common attribute to all Entity children.
So my question is how can I put _nextId in Entity class and have methods that change this value, while getting a different value for each child class.
Thank you.
Assuming Entity is abstract, you could create a :
protected abstract getNextId();
method which each concrete subclass will need to implement. That implementation can for example rely on a static counter.
You will have to hide it. Meaning you need to have the same variable in the subclasses as well.
If you declare a static variable in a superclass, all subclasses access the same variable until they hide it by declaring a variable with the same name themselves.

Java inherited method using the wrong class

So I have a parent class, here refered to as A, and class B which extends A.
public class A
{
private int a = 1;
public int getA()
{
return a;
}
}
public class B extends A
{
private int a = 2;
}
However, when B.getA() is called, it returns 1 from class A instead of the 2 in class B. Did I do something wrong? Because I had a similar problem a couple of months ago, and it miraculously worked after a lot of messing around. The only difference is that the method deals with adding an object to an ArrayList.
Thanks.
Private variables are private even to subclasses. A.a and B.a are two completely different fields. If you want to change data in a subclass, make it a protected field or (better yet) add an optionally abstract getter to the parent class and override it in the subclass.
The reason is that the fields defined in a class are never overriden in subclasses, irrespective of the fields' access modifiers.
If you declare a field in a subclass with the same name as a field in the superclass, your subclass actually has two fields with that name. The field inheritted from the superclass is hidden in the subclass, but (if the access rules permit it) the superclass version can be accessed in the subclass; e.g. by qualifying the field name with the class name.
(In your particular example, the access rules forbid B to access the a declared in A. A private field or method can only be accessed from the class itself or nested classes. But even so, there are two fields called a in any B instance instance.)

Categories