多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
### [陷阱:属性与静态方法](https://lingcoder.gitee.io/onjava8/#/book/09-Polymorphism?id=%e9%99%b7%e9%98%b1%ef%bc%9a%e5%b1%9e%e6%80%a7%e4%b8%8e%e9%9d%99%e6%80%81%e6%96%b9%e6%b3%95) 一旦学会了多态,就可以以多态的思维方式考虑每件事。然而,只有普通的方法调用可以是多态的。例如,如果你直接访问一个属性,该访问会在编译时解析: ~~~ // polymorphism/FieldAccess.java // Direct field access is determined at compile time class Super { public int field = 0; public int getField() { return field; } } class Sub extends Super { public int field = 1; @Override public int getField() { return field; } public int getSuperField() { return super.field; } } public class FieldAccess { public static void main(String[] args) { Super sup = new Sub(); // Upcast System.out.println("sup.field = " + sup.field + ", sup.getField() = " + sup.getField()); Sub sub = new Sub(); System.out.println("sub.field = " + sub.field + ", sub.getField() = " + sub.getField() + ", sub.getSuperField() = " + sub.getSuperField()) } } ~~~ 输出: ~~~ sup.field = 0, sup.getField() = 1 sub.field = 1, sub.getField() = 1, sub.getSuperField() = 0 ~~~ 当**Sub**对象向上转型为**Super**引用时,任何属性访问都被编译器解析,因此不是多态的。在这个例子中,**Super.field**和**Sub.field**被分配了不同的存储空间,因此,**Sub**实际上包含了两个称为**field**的属性:它自己的和来自**Super**的。然而,在引用**Sub**的**field**时,默认的**field**属性并不是**Super**版本的**field**属性。为了获取**Super**的**field**属性,需要显式地指明**super.field**。 尽管这看起来是个令人困惑的问题,实际上基本不会发生。首先,通常会将所有的属性都指明为**private**,因此不能直接访问它们,只能通过方法来访问。此外,你可能也不会给基类属性和派生类属性起相同的名字,这样做会令人困惑。 如果一个方法是静态(**static**)的,它的行为就不具有多态性: ~~~ // polymorphism/StaticPolymorphism.java // static methods are not polymorphic class StaticSuper { public static String staticGet() { return "Base staticGet()"; } public String dynamicGet() { return "Base dynamicGet()"; } } class StaticSub extends StaticSuper { public static String staticGet() { return "Derived staticGet()"; } @Override public String dynamicGet() { return "Derived dynamicGet()"; } } public class StaticPolymorphism { public static void main(String[] args) { StaticSuper sup = new StaticSub(); // Upcast System.out.println(StaticSuper.staticGet()); System.out.println(sup.dynamicGet()); } } ~~~ 输出: ~~~ Base staticGet() Derived dynamicGet() ~~~ 静态的方法只与类关联,与单个的对象无关。