【发布时间】:2011-01-29 08:03:49
【问题描述】:
我想知道:
- 为什么不能在 Java 中覆盖静态方法?
- 可以在 Java 中重载静态方法吗?
【问题讨论】:
标签: java static overloading overriding
我想知道:
【问题讨论】:
标签: java static overloading overriding
【讨论】:
静态方法不能被覆盖,因为没有什么可以覆盖的,因为它们是两种不同的方法。例如
static class Class1 {
public static int Method1(){
return 0;
}
}
static class Class2 extends Class1 {
public static int Method1(){
return 1;
}
}
public static class Main {
public static void main(String[] args){
//Must explicitly chose Method1 from Class1 or Class2
Class1.Method1();
Class2.Method1();
}
}
是的,静态方法可以像任何其他方法一样被重载。
【讨论】:
c1.Method1() 和c2.Method1() 调用同一个函数,事实上编译器会警告你以这种方式调用静态函数不是明智之举。
静态方法不能被覆盖,因为它们不会在运行时在对象实例上分派。编译器决定调用哪个方法。
这就是为什么您在编写时会收到编译器警告
MyClass myObject = new MyClass();
myObject.myStaticMethod();
// should be written as
MyClass.myStaticMethod()
// because it is not dispatched on myObject
myObject = new MySubClass();
myObject.myStaticMethod();
// still calls the static method in MyClass, NOT in MySubClass
静态方法可以重载(这意味着您可以为多个方法使用相同的方法名,只要它们具有不同的参数类型)。
Integer.parseInt("10");
Integer.parseInt("AA", 16);
【讨论】:
MySubClass.myStaticMethod)。
静态的父类方法不是子类的一部分(尽管它们是可访问的),因此不存在覆盖它的问题。即使您在子类中添加另一个静态方法,与父类中的静态方法相同,此子类静态方法也是唯一的,并且不同于其父类中的静态方法。
【讨论】:
静态方法不能被覆盖,因为它们不是对象状态的一部分。相反,它们属于类(即它们是类方法)。可以重载静态(和最终)方法。
【讨论】:
重载也称为静态绑定,所以只要使用静态这个词就意味着静态方法不能显示运行时多态性。
我们不能覆盖静态方法,但在超类及其子类中存在相同静态方法的不同实现是有效的。只是派生类会隐藏基类的实现。
对于静态方法,方法调用取决于引用的类型,而不是引用哪个对象,即静态方法只属于一个类而不属于它的实例,因此方法调用是在编译时决定的。
而在方法重载的情况下静态方法可以被重载 iff它们有不同的参数数量或类型。如果两个方法具有相同的名称和相同的参数列表,那么它们不能仅通过使用 'static' 关键字来定义不同。
【讨论】:
如果我使用子类名称 MysubClass 调用该方法,则子类方法显示它的含义静态方法可以被覆盖或不被覆盖
class MyClass {
static void myStaticMethod() {
System.out.println("Im in sta1");
}
}
class MySubClass extends MyClass {
static void myStaticMethod() {
System.out.println("Im in sta123");
}
}
public class My {
public static void main(String arg[]) {
MyClass myObject = new MyClass();
myObject.myStaticMethod();
// should be written as
MyClass.myStaticMethod();
// calling from subclass name
MySubClass.myStaticMethod();
myObject = new MySubClass();
myObject.myStaticMethod();
// still calls the static method in MyClass, NOT in MySubClass
}
}
【讨论】:
静态方法是一种方法,其单一副本由类的所有对象共享。静态方法属于类而不是对象。由于静态方法不依赖于对象,Java编译器不需要等到对象创建。所以调用静态方法我们使用像ClassName.method()这样的语法;
在方法重载的情况下,方法应该在同一个类中进行重载。即使它们被声明为静态,也可以将它们重载为,
Class Sample
{
static int calculate(int a,int b,int c)
{
int res = a+b+c;
return res;
}
static int calculate(int a,int b)
{
int res = a*b;
return res;
}
}
class Test
{
public static void main(String []args)
{
int res = Sample.calculate(10,20,30);
}
}
但是在方法覆盖的情况下,超类中的方法和子类中的方法充当不同的方法。超类将拥有自己的副本,子类将拥有自己的副本,因此它不会被方法覆盖。
【讨论】:
不,静态方法不能被覆盖,因为它是类而不是对象的一部分。 但是可以重载静态方法。
【讨论】:
class SuperType {
public static void classMethod(){
System.out.println("Super type class method");
}
public void instancemethod(){
System.out.println("Super Type instance method");
}
}
public class SubType extends SuperType{
public static void classMethod(){
System.out.println("Sub type class method");
}
public void instancemethod(){
System.out.println("Sub Type instance method");
}
public static void main(String args[]){
SubType s=new SubType();
SuperType su=s;
SuperType.classMethod();// Prints.....Super type class method
su.classMethod(); //Prints.....Super type class method
SubType.classMethod(); //Prints.....Sub type class method
}
}
这个静态方法覆盖的例子
注意:如果我们调用带有对象引用的静态方法,那么将调用引用类型(类)静态方法,而不是对象类静态方法。
静态方法只属于类。
【讨论】:
【讨论】:
使用静态方法的真正目的是在不为其创建实例的情况下访问类的方法。如果我们重写该方法将毫无意义,因为它们将通过 classname.method() 访问
【讨论】:
不,您不能覆盖静态方法。静态解析针对类,而不是实例。
public class Parent {
public static String getCName() {
return "I am the parent";
}
}
public class Child extends Parent {
public static String getCName() {
return "I am the child";
}
}
每个类都有一个静态方法getCName()。当您调用类名称时,它的行为与您预期的一样,并且每个都返回预期值。
@Test
public void testGetCNameOnClass() {
assertThat(Parent.getCName(), is("I am the parent"));
assertThat(Child.getCName(), is("I am the child"));
}
在这个单元测试中没有惊喜。但这不是压倒一切的。这声明了一些有名称冲突的东西。
如果我们尝试从类的实例中获取静态(不是一个好习惯),那么它确实显示:
private Parent cp = new Child();
`enter code here`
assertThat(cp.getCName(), is("I am the parent"));
即使 cp 是 Child,静态也是通过声明的类型 Parent 解析的,而不是对象的实际类型。对于非静态,这是正确解决的,因为非静态方法可以覆盖其父方法。
【讨论】:
您可以重载静态方法,但不能覆盖静态方法。实际上,您可以在子类中重写静态方法,但这不称为覆盖,因为覆盖应该与多态性和动态绑定有关。静态方法属于类,因此与这些概念无关。静态方法的重写更像是一种阴影。
【讨论】:
我设计了一个静态方法覆盖的代码。我认为它很容易被覆盖。请告诉我它是如何无法覆盖静态成员的。这是我的代码-
class Class1 {
public static int Method1(){
System.out.println("true");
return 0;
}
}
class Class2 extends Class1 {
public static int Method1(){
System.out.println("false");
return 1;
}
}
public class Mai {
public static void main(String[] args){
Class2 c=new Class2();
//Must explicitly chose Method1 from Class1 or Class2
//Class1.Method1();
c.Method1();
}
}
【讨论】:
其实很容易理解——所有标记为static的东西都只属于类,例如静态方法不能在子类中继承,因为它们属于声明它们的类。参考静态关键字。
我发现这个问题的最佳答案是:
http://www.geeksforgeeks.org/can-we-overload-or-override-static-methods-in-java/
【讨论】:
由于任何静态方法都是类的一部分而不是实例,因此无法覆盖静态方法
【讨论】:
来自Why doesn't Java allow overriding of static methods?
覆盖取决于拥有一个类的实例。多态性的要点是您可以子类化一个类,并且实现这些子类的对象对于超类中定义的相同方法(并在子类中被覆盖)具有不同的行为。静态方法不与类的任何实例相关联,因此该概念不适用。
有两个因素推动 Java 的设计影响了这一点。一个是对性能的担忧:有很多批评 Smalltalk 太慢(垃圾收集和多态调用是其中的一部分),Java 的创建者决心避免这种情况。另一个决定是 Java 的目标受众是 C++ 开发人员。使静态方法以它们确实的方式工作有利于 C++ 程序员熟悉,而且速度也非常快,因为无需等到运行时才能确定要调用的方法。
【讨论】:
当然,我们不能覆盖 Java 中的静态方法。 因为 JVM 在运行时通过使用 Java 中的动态绑定来解析基于对象的正确覆盖方法。
然而,Java 中的静态方法与 Class 而非对象相关联,并在编译时解析和绑定。
【讨论】: