我对私有方法如何可以是静态的而公共方法必须是动态绑定的有点困惑。
5 回答
动态绑定意味着在运行时决定运行哪些代码。这是多态性的基础。
公共、包访问和受保护方法是动态绑定的。子类可以覆盖这些方法并提供替代实现。私有方法不能被覆盖,因此它们不需要动态绑定。
静态方法不是动态绑定的(名称中的线索),因为它们是在类本身上定义的,而不是对每个对象都是唯一的。
动态绑定或后期绑定
动态绑定是指编译器无法解析调用并且绑定仅在运行时完成的情况。让我们试着理解这一点。假设我们有一个名为的类SuperClass
,另一个名为SubClass
扩展它的类。现在SuperClass
也可以将引用分配给该类型的对象SubClass
。如果我们有一个方法(比如someMethod()
)SuperClass
,我们在其中覆盖,SubClass
那么对该引用的该方法的调用SuperClass
只能在运行时解析,因为编译器无法确定该引用将指向什么类型的对象运行。
...
SuperClass superClass1 = new SuperClass();
SuperClass superClass2 = new SubClass();
...
superClass1.someMethod(); // SuperClass version is called
superClass2.someMethod(); // SubClass version is called
....
在这里,我们看到尽管对象引用superClass1
和superClass2
都SuperClass
只是类型,但在运行时它们分别引用了 SuperClass 和 类型的对象SubClass
。
因此,在编译时,编译器无法确定someMethod()
对这些引用上的方法的调用是否实际引用了该方法的哪个版本——超类版本或子类版本。
因此,我们看到 Java 中的动态绑定只是根据实际对象类型绑定方法调用(仅继承方法,因为它们可以在子类中被覆盖,因此编译器可能不确定要调用哪个版本的方法)和不在对象引用的声明类型上。
静态绑定或早期绑定
如果编译器只能在编译时解析绑定,那么这种绑定称为静态绑定或早期绑定。所有实例方法调用总是在运行时解析,但所有静态方法调用都在编译时解析,因此我们对静态方法调用进行了静态绑定。因为静态方法是类方法,因此可以使用类名本身来访问它们(实际上,它们被鼓励仅使用相应的类名而不是使用对象引用来使用),因此需要解析对它们的访问在编译时只使用编译时类型信息。这就是静态方法实际上不能被覆盖的原因。阅读更多——你能在 Java 中重写静态方法吗?
对 Java 中所有成员变量的访问遵循静态绑定,因为 Java 不支持(事实上,它不鼓励)成员变量的多态行为。
[除了这个讨论,你不能覆盖Java 中的静态(如上面的链接所述)、私有和最终方法。]
如果您不需要方法中的this
引用private
,您也可以制作它static
,它不会有任何区别。在任何一种private
情况下都不需要动态绑定方法,因此在实现级别上,您选择哪种方法真的无关紧要。但是,当您标记方法时,它有助于提高可读性,static
从那时起,很明显该方法不依赖于对象的状态。
静态方法是类级别的方法,因此您只能通过类名访问,但方法必须是公共的
1.在类多态中,子类的对象引用变量作为参数传递给接受参数的方法,该参数是超类类型的对象引用变量。Public and Protected and Default members can be dynamically bounded
, private 成员不是不被继承。
2.静态成员是类的,它不绑定到任何单个对象,所以它不是动态绑定的。