`
fantaxy025025
  • 浏览: 1251169 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

朝花夕拾:java-向上转型中变量覆盖要小心使用_继承过程中Java子类父类属性的覆盖问题

 
阅读更多

====

现在的代码结构设计的复杂起来了,为了后来人编写效率。

需要实验确定整个结构运行如同预期。

 

两个系的类如何兼容。两串类系如何兼容融合。

====

总结:

1. 仔细理解类和实例的区别。

在实例化时,会根据类的定义进行,类中的成员变量都会分配空间。

这里注意:

    *父类的成员变量和子类的成员变量都是独自的独立的!!!也就是说子类的成员变量名字完全可以父类相同,没有关系。

    *父类的方法与子类的方法,虽然不用分配空间,但是也是独立的。

2. 调用区别。

    *当调用方法时,不管有没有向上转型,都是调用真实实例的方法。

    *当调用实例变量时,如果有向上转型(比如parentClass),则调用上层的实例变量(parentClass的实例变量),而不是真实实例的实例变量。

     这点区别是巨大的!!!也是一个大坑。

 

6. 如何规避上面2的坑?

1继承时,也最好不用相通的实例名字。

2既然使用了public和protected来方便底层类继承实例变量,那就不要再次定义一个自己的。这样保证使用的是一份。

 

为什么向上转型时,方法调用使用真实实例的,而成员变量则使用父类的?编译器的原因!

1实例变量可以重名,且属于自己的独立空间。

    所以,可以独立引用到也必须独立引用,这样程序才是正确的。

    但是,向上转型时,没有使用真实实例的成员变量,而是使用的父类的成员变量。编译器这么搞,其实是不科学的!!!

2方法,也是独立的,但不用分配空间。

    方法调用时,永远使用的是“真实实例的方法”,这就是编译器的真实机制。

 

 

=

直接看实验代码:

class ParentClass {
    private String privateField = "父类变量--private";

    /* friendly */String friendlyField = "父类变量--friendly";

    protected String protectedField = "父类变量--protected";

    public String publicField = "父类变量--public";

    // private的变量无法直接访问,因此我们给他增加了一个访问方法
    public String getPrivateFieldValue() {
        System.out.println("\tcall method: ParentClass.getPrivateFieldValue");
        return privateField;
    }
    public String getProtectedFieldValue() {
        System.out.println("\tcall method: ParentClass.getProtectedFieldValue");
        return protectedField;
    }
}

class SubClass extends ParentClass {
    private String privateField = "子类变量--private";

    /* friendly */String friendlyField = "子类变量--friendly";

    protected String protectedField = "子类变量--protected";

    public String publicField = "子类变量--public";

    // private的变量无法直接访问,因此我们给他增加了一个访问方法
    public String getPrivateFieldValue() {
        System.out.println("\tcall method: SubClass.getPrivateFieldValue");
        return privateField;
    }

    public String getProtectedFieldValue() {
        System.out.println("\tcall method: SubClass.getProtectedFieldValue");
        return this.protectedField;
    }

    public String getProtectedFieldValue_bySuper() {
        return super.protectedField;
    }

    public String call_super_method_in_sub_class__call_super_method_getProtectedFieldValue() {
        System.out.println("\tcall mothed: SubClass.call_super_method_in_sub_class__call_super_method_getProtectedFieldValue");
        return super.getProtectedFieldValue();
    }
    public String call_super_method_in_sub_class__call_super_method_getPrivateFieldValue() {
        System.out.println("\tcall mothed: SubClass.call_super_method_in_sub_class__call_super_method_getPrivateFieldValue");
        return super.getPrivateFieldValue();
    }
}
class SubClass_notOverWrite extends ParentClass {
    private String privateField = "子类变量--private";

    public SubClass_notOverWrite() {
        super.friendlyField = "子类变量--friendly";
        this.protectedField = "子类变量--protected";
        this.publicField = "子类变量--public";
    }

    // private的变量无法直接访问,因此我们给他增加了一个访问方法
    public String getPrivateFieldValue() {
        System.out.println("\tcall method: SubClass_notOverWrite.getPrivateFieldValue");
        return privateField;
    }

    public String getProtectedFieldValue() {
        System.out.println("\tcall method: SubClass_notOverWrite.getProtectedFieldValue");
        return this.protectedField;
    }

    public String getProtectedFieldValue_bySuper() {
        return super.protectedField;
    }

    public String call_super_method_in_sub_class__call_super_method_getProtectedFieldValue() {
        System.out.println("\tcall mothed: SubClass_notOverWrite.call_super_method_in_sub_class__call_super_method_getProtectedFieldValue");
        return super.getProtectedFieldValue();
    }
    public String call_super_method_in_sub_class__call_super_method_getPrivateFieldValue() {
        System.out.println("\tcall mothed: SubClass_notOverWrite.call_super_method_in_sub_class__call_super_method_getPrivateFieldValue");
        return super.getPrivateFieldValue();
    }
}


public class StudyExtends {
    public static void main(String[] args) {
        // 为了便于查阅,我们统一按照private、friendly、protected、public的顺序
        // 输出下列三种情况中变量的值

        // ParentClass类型,ParentClass对象
        ParentClass realParentClass = new ParentClass();
        System.out.println("ParentClass realParentClass = new ParentClass();");
        System.out.println("realParentClass.getPrivateFieldValue()" + "==>>" + realParentClass.getPrivateFieldValue());
        System.out.println("realParentClass.getProtectedFieldValue()" + "==>>" + realParentClass.getProtectedFieldValue());
        System.out.println("realParentClass.friendlyField" + "==>>" + realParentClass.friendlyField);
        System.out.println("realParentClass.protectedField" + "==>>" + realParentClass.protectedField);
        System.out.println("realParentClass.publicField" + "==>>" + realParentClass.publicField);

        System.out.println();

        // ParentClass类型,SubClass对象
        ParentClass subClassUpcast2ParentClass = new SubClass();
        System.out.println("ParentClass subClassUpcast2ParentClass = new SubClass();");
        System.out.println("subClassUpcast2ParentClass.getPrivateFieldValue()" + "==>>" + subClassUpcast2ParentClass.getPrivateFieldValue());
        System.out.println("subClassUpcast2ParentClass.getProtectedFieldValue()" + "==>>" + subClassUpcast2ParentClass.getProtectedFieldValue());
        System.out.println("subClassUpcast2ParentClass.friendlyField" + "==>>" + subClassUpcast2ParentClass.friendlyField);
        System.out.println("subClassUpcast2ParentClass.protectedField" + "==>>" + subClassUpcast2ParentClass.protectedField);
        System.out.println("subClassUpcast2ParentClass.publicField" + "==>>" + subClassUpcast2ParentClass.publicField);

        System.out.println();

        // SubClass类型,SubClass对象
        SubClass realSubClass = new SubClass();
        System.out.println("SubClass realSubClass = new SubClass();");
        System.out.println("realSubClass.getPrivateFieldValue()" + "==>>" + realSubClass.getPrivateFieldValue());
        System.out.println("realSubClass.getProtectedFieldValue()" + "==>>" + realSubClass.getProtectedFieldValue());
        System.out.println("realSubClass.getProtectedFieldValue_bySuper()" + "==>>" + realSubClass.getProtectedFieldValue_bySuper());
        System.out.println("realSubClass.friendlyField" + "==>>" + realSubClass.friendlyField);
        System.out.println("realSubClass.protectedField" + "==>>" + realSubClass.protectedField);
        System.out.println("realSubClass.publicField" + "==>>" + realSubClass.publicField);
        //++
        System.out.println("realSubClass.call_super_method_in_sub_class__call_super_method_getPrivateFieldValue" + "==>>" + realSubClass.call_super_method_in_sub_class__call_super_method_getPrivateFieldValue());
        System.out.println("realSubClass.call_super_method_in_sub_class__call_super_method_getProtectedFieldValue" + "==>>" + realSubClass.call_super_method_in_sub_class__call_super_method_getProtectedFieldValue());

        System.out.println();

        // ParentClass类型,SubClass对象
        ParentClass subClassUpcast2ParentClass_notOverWrite = new SubClass_notOverWrite();
        System.out.println("ParentClass subClassUpcast2ParentClass_notOverWrite = new SubClass_notOverWrite();");
        System.out.println("subClassUpcast2ParentClass_notOverWrite.getPrivateFieldValue()" + "==>>" + subClassUpcast2ParentClass_notOverWrite.getPrivateFieldValue());
        System.out.println("subClassUpcast2ParentClass_notOverWrite.getProtectedFieldValue()" + "==>>" + subClassUpcast2ParentClass_notOverWrite.getProtectedFieldValue());
        System.out.println("subClassUpcast2ParentClass_notOverWrite.friendlyField" + "==>>" + subClassUpcast2ParentClass_notOverWrite.friendlyField);
        System.out.println("subClassUpcast2ParentClass_notOverWrite.protectedField" + "==>>" + subClassUpcast2ParentClass_notOverWrite.protectedField);
        System.out.println("subClassUpcast2ParentClass_notOverWrite.publicField" + "==>>" + subClassUpcast2ParentClass_notOverWrite.publicField);

        System.out.println();

        // SubClass类型,SubClass对象
        SubClass_notOverWrite realSubClass_notOverWrite = new SubClass_notOverWrite();
        System.out.println("SubClass realSubClass_notOverWrite = new SubClass_notOverWrite();");
        System.out.println("realSubClass_notOverWrite.getPrivateFieldValue()" + "==>>" + realSubClass_notOverWrite.getPrivateFieldValue());
        System.out.println("realSubClass_notOverWrite.getProtectedFieldValue()" + "==>>" + realSubClass_notOverWrite.getProtectedFieldValue());
        System.out.println("realSubClass_notOverWrite.getProtectedFieldValue_bySuper()" + "==>>" + realSubClass_notOverWrite.getProtectedFieldValue_bySuper());
        System.out.println("realSubClass_notOverWrite.friendlyField" + "==>>" + realSubClass_notOverWrite.friendlyField);
        System.out.println("realSubClass_notOverWrite.protectedField" + "==>>" + realSubClass_notOverWrite.protectedField);
        System.out.println("realSubClass_notOverWrite.publicField" + "==>>" + realSubClass_notOverWrite.publicField);
        //++
        System.out.println("realSubClass.call_super_method_in_sub_class__call_super_method_getPrivateFieldValue" + "==>>" + realSubClass_notOverWrite.call_super_method_in_sub_class__call_super_method_getPrivateFieldValue());
        System.out.println("realSubClass.call_super_method_in_sub_class__call_super_method_getProtectedFieldValue" + "==>>" + realSubClass_notOverWrite.call_super_method_in_sub_class__call_super_method_getProtectedFieldValue());

    }
}

 

运行结果:

ParentClass realParentClass = new ParentClass();

call method: ParentClass.getPrivateFieldValue

realParentClass.getPrivateFieldValue()==>>父类变量--private

call method: ParentClass.getProtectedFieldValue

realParentClass.getProtectedFieldValue()==>>父类变量--protected

realParentClass.friendlyField==>>父类变量--friendly

realParentClass.protectedField==>>父类变量--protected

realParentClass.publicField==>>父类变量--public

 

ParentClass subClassUpcast2ParentClass = new SubClass();

call method: SubClass.getPrivateFieldValue

subClassUpcast2ParentClass.getPrivateFieldValue()==>>子类变量--private

call method: SubClass.getProtectedFieldValue

subClassUpcast2ParentClass.getProtectedFieldValue()==>>子类变量--protected

subClassUpcast2ParentClass.friendlyField==>>父类变量--friendly

subClassUpcast2ParentClass.protectedField==>>父类变量--protected

subClassUpcast2ParentClass.publicField==>>父类变量--public

 

SubClass realSubClass = new SubClass();

call method: SubClass.getPrivateFieldValue

realSubClass.getPrivateFieldValue()==>>子类变量--private

call method: SubClass.getProtectedFieldValue

realSubClass.getProtectedFieldValue()==>>子类变量--protected

realSubClass.getProtectedFieldValue_bySuper()==>>父类变量--protected

realSubClass.friendlyField==>>子类变量--friendly

realSubClass.protectedField==>>子类变量--protected

realSubClass.publicField==>>子类变量--public

call mothed: SubClass.call_super_method_in_sub_class__call_super_method_getPrivateFieldValue

call method: ParentClass.getPrivateFieldValue

realSubClass.call_super_method_in_sub_class__call_super_method_getPrivateFieldValue==>>父类变量--private

call mothed: SubClass.call_super_method_in_sub_class__call_super_method_getProtectedFieldValue

call method: ParentClass.getProtectedFieldValue

realSubClass.call_super_method_in_sub_class__call_super_method_getProtectedFieldValue==>>父类变量--protected

 

ParentClass subClassUpcast2ParentClass_notOverWrite = new SubClass_notOverWrite();

call method: SubClass_notOverWrite.getPrivateFieldValue

subClassUpcast2ParentClass_notOverWrite.getPrivateFieldValue()==>>子类变量--private

call method: SubClass_notOverWrite.getProtectedFieldValue

subClassUpcast2ParentClass_notOverWrite.getProtectedFieldValue()==>>子类变量--protected

subClassUpcast2ParentClass_notOverWrite.friendlyField==>>子类变量--friendly

subClassUpcast2ParentClass_notOverWrite.protectedField==>>子类变量--protected

subClassUpcast2ParentClass_notOverWrite.publicField==>>子类变量--public

 

SubClass realSubClass_notOverWrite = new SubClass_notOverWrite();

call method: SubClass_notOverWrite.getPrivateFieldValue

realSubClass_notOverWrite.getPrivateFieldValue()==>>子类变量--private

call method: SubClass_notOverWrite.getProtectedFieldValue

realSubClass_notOverWrite.getProtectedFieldValue()==>>子类变量--protected

realSubClass_notOverWrite.getProtectedFieldValue_bySuper()==>>子类变量--protected

realSubClass_notOverWrite.friendlyField==>>子类变量--friendly

realSubClass_notOverWrite.protectedField==>>子类变量--protected

realSubClass_notOverWrite.publicField==>>子类变量--public

call mothed: SubClass_notOverWrite.call_super_method_in_sub_class__call_super_method_getPrivateFieldValue

call method: ParentClass.getPrivateFieldValue

realSubClass.call_super_method_in_sub_class__call_super_method_getPrivateFieldValue==>>父类变量--private

call mothed: SubClass_notOverWrite.call_super_method_in_sub_class__call_super_method_getProtectedFieldValue

call method: ParentClass.getProtectedFieldValue

realSubClass.call_super_method_in_sub_class__call_super_method_getProtectedFieldValue==>>子类变量--protected

 

Process finished with exit code 0

 

 

 

 

 

参考:https://www.iteye.com/blog/gaolixu-363709 有改动和优化实验。

=

=

=

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics