本博文属于“自我理解”性质,主要基于“Java编译程序实现角度”推导而来。
考虑“继承”场景,继承子类(具体类和接口)允许包含“原生成员”和“继承成员”,非继承子类(即“顶层具体类java.lang.Object
”和“顶层接口”)只允许包含“原生成员”。
一、原生成员和继承成员
1.1、原生成员
原生成员:在本类自身中定义的成员。包括:原生字段(一般字段,静态字段)和原生方法(一般方法,静态方法)。
1.2、继承成员
继承成员:在父类或者祖先类中定义且能够继承到本类的成员。包括:继承字段(一般字段,静态字段)和继承方法(一般方法,静态方法)。
对于每个继承成员,存在一条继承引用链,假设继承引用链有N个节点,则N>=2,且前N-1个节点对应于“继承成员”,最后1个节点对应于“原生成员”,具体可参见“二、Java类实际定义”中的3个例子。
二、Java类实际定义
Java类的实际定义应该既包含“原生成员”,也包含“继承成员”,这样它的定义才是完整的。当类的定义是完整的,后续再涉及到该类时,可以无需再考虑该类的父类及祖先类,即只需考虑该类自身即可。
接下来是几个例子。
1、例子1
示例代码如下:
1 | package chapter6; |
从chapter6.PracticalClass.a
开始有一条引用链:chapter6.PracticalClass.a -> chapter6.BB.a -> chapter6.AA.a
。
从chapter6.PracticalClass.f()
开始有一条引用链:chapter6.PracticalClass.f() -> chapter6.BB.f() -> chapter6.AA.f()
。
从chapter6.PracticalClass.c
开始有一条引用链:chapter6.PracticalClass.c -> chapter6.BB.c
。
从chapter6.PracticalClass.g()
开始有一条引用链:chapter6.PracticalClass.g() -> chapter6.BB.g()
。
2、例子2
1 | package chapter6; |
从chapter6.IC.a
开始有一条引用链:chapter6.IC.a -> chapter6.IB.a -> chapter6.IA.a
。
从chapter6.IC.f()
开始有一条引用链:chapter6.IC.f() -> chapter6.IB.f() -> chapter6.IA.f()
。
从chapter6.IC.b
开始有一条引用链:chapter6.IC.b -> chapter6.IB.b
。
从chapter6.IC.g()
开始有一条引用链:chapter6.IC.g() -> chapter6.IB.g()
。
3、例子3
1 | package chapter6; |
从chapter6.ICE.a
开始有一条引用链:chapter6.ICE.a -> chapter6.ICA.a
。
从chapter6.ICE.f()
开始有一条引用链:chapter6.ICE.f() -> chapter6.ICA.f()
。
从chapter6.ICE.a
开始有一条引用链:chapter6.ICE.a -> chapter6.ICB.a -> chapter6.ICA.a
。
从chapter6.ICE.f()
开始有一条引用链:chapter6.ICE.f() -> chapter6.ICB.f() -> chapter6.ICA.f()
。
从chapter6.ICE.b
开始有一条引用链:chapter6.ICE.b -> chapter6.ICB.b
。
从chapter6.ICE.g()
开始有一条引用链:chapter6.ICE.g() -> chapter6.ICB.g()
。
从chapter6.ICE.c
开始有一条引用链:chapter6.ICE.c -> chapter6.ICD.c
。
从chapter6.ICE.h()
开始有一条引用链:chapter6.ICE.h() -> chapter6.ICD.h()
。
三、其他
本博文只关注“Java类实际定义”的核心概念,因此未考虑实际情形中的几个约束条件,比如如下代码会提示Instance method 'f()' in 'chapter6.ICG' cannot override static method 'f()' in 'chapter6.ICF'
编译错误:
1 | package chapter6; |