Java 在子类的对象上调用direct时的静态和私有方法行为听起来像是重写?
在R&D中,我在privateMethod()的情况下发现了这个方法-因为这个方法在子类的对象上不可用,所以子类和父类的privateMethod()是单独的方法,它们没有关系,所以这不是重写。 但在staticMethod()的情况下-父类的方法在子类的对象上可用,当我们在子类中定义此方法时,子类的对象开始指向子类方法。这看起来像方法重写,但不是,因为静态方法不重写。 java开发工具包如何处理静态方法Java 在子类的对象上调用direct时的静态和私有方法行为听起来像是重写?,java,static,private,overriding,access-specifier,Java,Static,Private,Overriding,Access Specifier,在R&D中,我在privateMethod()的情况下发现了这个方法-因为这个方法在子类的对象上不可用,所以子类和父类的privateMethod()是单独的方法,它们没有关系,所以这不是重写。 但在staticMethod()的情况下-父类的方法在子类的对象上可用,当我们在子类中定义此方法时,子类的对象开始指向子类方法。这看起来像方法重写,但不是,因为静态方法不重写。 java开发工具包如何处理静态方法 public class B extends A{ public static
public class B extends A{
public static void main(String[] args) {
new B().privateMethod();//no error -output B-privateMethod.Sounds like overriding
new B().staticMethod(); //no error -output B-StaticMethod.Sounds like overriding
}
private void privateMethod() {
System.out.println("B-privateMethod.");
}
static void staticMethod() {
System.out.println("B-StaticMethod.");
}
}
class A{
private void privateMethod() {
System.out.println("A-privateMethod.");
}
static void staticMethod() {
System.out.println("A-StaticMethod.");
}
}
这不是重写,因为B没有看到A的privateMethod()
这不是重写,允许通过实例调用静态方法,尽管这可能会让人困惑。它与通过类名调用它完全相同-B.staticMethod()
。如果B
的超类a
有一个从B
可见的静态方法,则可以从B
调用该方法(无论您是编写B.staticMethod()
还是a.staticMethod()
还是new B().staticMethod()
,都没有关系)
如果以后在
B
中定义了同名的静态方法,该方法会在a
中隐藏同名的方法,因此调用B.staticMethod()
或new B().staticMethod()
现在调用B
的静态方法。但是,调用a.staticMethod()
仍将调用一个的静态方法。多态性不适用于静态方法。使用JVM指令invokestatic调用静态方法,而使用invokevirtual实现多态性。对静态方法的调用在编译时确定,多态方法在运行时动态调度
只需将新的B()赋值给类型为A的变量,就可以轻松地调整代码,从而调用A.staticMethod()
new B().staticMethod();
不要在同一句话中谈论static和override
整个可重写方法的概念是在运行时动态绑定要执行的方法。
public static void main(String[] args) {
new B().privateMethod();
A b = new B(); // change here.
b.staticMethod(); // A.staticMethod() is called here.
}
虽然变量obj
的类型为A
,但它仍然打印出“B”
另一方面,静态方法在编译时绑定。这意味着编译器使用变量类型(或表达式)来确定要执行的方法:
class A { void print() { out.println("A"); }
class B extends A { void print() { out.println("B"); }
A obj = new B();
obj.print();
这现在会产生“A”。不幸的是,Java语言允许对变量或表达式调用静态方法。不建议这样做!最好对类型本身调用静态方法:
class A { static void print() { out.println("A"); }
class B extends A { static void print() { out.println("B"); }
A obj = new B();
obj.print();
在第一个示例中-obj.print();
-编译器自动将语句转换为A.print()
。实际对象不计算在内。事实上,您可以编写以下代码:
A.print();
B.print();
或:
仍然打印“A”。静态成员不会被覆盖,而是被隐藏。new B().staticMethod();=>这是一种错误的方法。你会让其他人相信它是一种实例方法。调用此方法的正确方法是:B.staticMethod();请您评论一下方法隐藏和重写之间的区别,除了静态方法的调用在编译时由JVM指令invokestatic调用确定,而多态性是在运行时由invokevirtual实现的,以获得更清晰的信息。@dubey theHarcourtians听起来您是在要求我复制内容从另一个答案到我的答案。这听起来不对。我的意思是,除了在编译时根据引用确定的隐藏之外,你可以更清楚地了解它,因为当没有引用意味着它被对象编译器调用时,编译器会假定你在运行时创建的对象的类名,作为静态情况下的引用。
A.print();
B.print();
A obj = null;
obj.print();
((A) null).print();