Overlay of Java Subclass Parent Attributes

Posted by cesar_ser on Fri, 05 Jul 2019 22:44:37 +0200

class ParentClass {   
    public int i = 10;   
}   
  
public class SubClass extends ParentClass {   
    public int i = 30;   
  
    public static void main(String[] args) {   
        ParentClass parentClass = new SubClass();   
        SubClass subClass = new SubClass();   
        System.out.println(parentClass.i + subClass.i);   
    }   
}

What is the output of the console? 20? 40? Or 60?



Variables, or attributes of classes, in the case of inheritance, what happens if there are variables with the same name between parent and child classes? This is the coverage of variables (attributes), which is the knowledge point to be examined in this question.  

The problem is simple, but the situation is complicated. Because we need to consider not only variables, static variables and constants, but also private, friendly (that is, without access modifiers), protected and public access rights under the different impact of attributes.  

Let's start with ordinary variables. In accordance with our usual practice, let's first look at a piece of code:

 

class ParentClass {   
    private String privateField = "Parent variables--private";   
  
    /* friendly */String friendlyField = "Parent variables--friendly";   
  
    protected String protectedField = "Parent variables--protected";   
  
    public String publicField = "Parent variables--public";   
  
    // private variables cannot be accessed directly, so we added an access method to them.   
    public String getPrivateFieldValue() {   
        return privateField;   
    }   
}   
  
public class SubClass extends ParentClass {   
    private String privateField = "Subclass variables--private";   
  
    /* friendly */String friendlyField = "Subclass variables--friendly";   
  
    protected String protectedField = "Subclass variables--protected";   
  
    public String publicField = "Subclass variables--public";   
  
    // private variables cannot be accessed directly, so we added an access method to them.   
    public String getPrivateFieldValue() {   
        return privateField;   
    }   
  
    public static void main(String[] args) {   
        // For ease of reference, we unified the order of private, friendly, protected and public.   
        // Output the values of variables in the following three cases   
  
        // ParentClass type, ParentClass object   
        ParentClass parentClass = new ParentClass();   
        System.out.println("ParentClass parentClass = new ParentClass();");   
        System.out.println(parentClass.getPrivateFieldValue());   
        System.out.println(parentClass.friendlyField);   
        System.out.println(parentClass.protectedField);   
        System.out.println(parentClass.publicField);   
  
        System.out.println();   
  
        // ParentClass type, SubClass object   
        ParentClass subClass = new SubClass();   
        System.out.println("ParentClass subClass = new SubClass();");   
        System.out.println(subClass.getPrivateFieldValue());   
        System.out.println(subClass.friendlyField);   
        System.out.println(subClass.protectedField);   
        System.out.println(subClass.publicField);   
  
        System.out.println();   
  
        // SubClass type, SubClass object   
        SubClass subClazz = new SubClass();   
        System.out.println("SubClass subClazz = new SubClass();");   
        System.out.println(subClazz.getPrivateFieldValue());   
        System.out.println(subClazz.friendlyField);   
        System.out.println(subClazz.protectedField);   
        System.out.println(subClazz.publicField);   
    }   
}  

The results of this code are as follows:

ParentClass parentClass = new ParentClass(); 
Parent variable -- private 
Parent variable--friendly 
Parent variable -- protected 
Parent variable -- public 

ParentClass subClass = new SubClass(); 
Subclass variable -- private 
Parent variable--friendly 
Parent variable -- protected 
Parent variable -- public 

SubClass subClazz = new SubClass(); 
Subclass variable -- private 
Subclass variable--friendly 
Subclass variable -- protected 
Subclass variable -- public 


As can be seen from the above results, the private variable is different from the other three access permission variables, which is caused by override of the method. A review of rewriting knowledge is left to later chapters. Here we look at the coverage of variables under the other three access permissions.  

Analyzing the output above shows that the value of a variable depends on the type of variable we define, not the type of object we create.  

In the example above, the access rights of variables with the same name are the same, so what happens to variables with the same name but different access rights? Facts speak louder than words. Let's go on with the test. Because of the particularity of the private variable, we excluded it from the next experiment.  

Since the above example has shown that when the variable type is ParentClass, no matter whether the object we create is ParentClass or SubClass, there is no problem of attribute coverage, so we only consider that the variable type and the object we create are all subclasses. Situation.

 

class ParentClass {   
    /* friendly */String field = "Parent variables";   
}   
  
public class SubClass extends ParentClass {   
    protected String field = "Subclass variables";   
  
    public static void main(String[] args) {   
        SubClass subClass = new SubClass();   
        System.out.println(subClass.field);   
    }   
}  

Operation results:

Subclass variables

class ParentClass {   
    public String field = "Parent variables";   
}   
  
public class SubClass extends ParentClass {   
    protected String field = "Subclass variables";   
  
    public static void main(String[] args) {   
        SubClass subClass = new SubClass();   
        System.out.println(subClass.field);   
    }   
}  

Operation results:

Subclass variables


The output of the above two different pieces of code is exactly the same. In fact, we can switch the access modifiers before the parent and child class attributes between friendly, protected and public arbitrarily, and the results are the same. That is to say, access modifiers do not affect the coverage of attributes, and you can write your own test code to verify this.  

What about static variables and constants? Let's continue to see:

 

class ParentClass {   
    public static String staticField = "Parent static variable";   
  
    public final String finalField = "Parental Constants";   
  
    public static final String staticFinalField = "Parent static constant";   
}   
  
public class SubClass extends ParentClass {   
    public static String staticField = "Subclass static variables";   
  
    public final String finalField = "Subclass Constants";   
  
    public static final String staticFinalField = "Subclass static constants";   
  
    public static void main(String[] args) {   
        SubClass subClass = new SubClass();   
        System.out.println(SubClass.staticField);   
        System.out.println(subClass.finalField);   
        System.out.println(SubClass.staticFinalField);   
    }   
}  

The results are as follows:

Subclass static variables

Subclass Constants

Subclass static constants



Although the results above contain "static variables of subclasses" and "static constants of subclasses", this does not mean that "static variables" and "static constants" of the parent class can be overridden by subclasses, because they belong to classes rather than objects.  

In the example above, we have been using objects to test the coverage of variables (attributes). If it was a basic type of variable, would the results be the same? The answer is yes. Here we will not give examples one by one.  

Finally, let's make a summary. Through the above tests, we can draw a conclusion that:

Because the private variable is restricted by access rights, it cannot be overridden.  
The value of an attribute depends not on the type of object we create, but on the type of variable we define.  
The friendly, protected, and public modifiers do not affect the coverage of attributes.  
Static variables and static constants belong to classes and do not belong to objects, so they cannot be overwritten.  
Constants can be overwritten.  
For basic types and objects, they apply the same rule of coverage.  

Finally, let's go back to the question at the beginning. I think the answer is already known. The result is 40.

Topics: Attribute