我想知道:
- 为什么在Java中不能覆盖静态方法?
- 可以在Java中重载静态方法吗?
Answers:
静态方法不能被覆盖,因为没有什么可以覆盖的,因为它们将是两个不同的方法。例如
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
)。
静态的父类方法不属于子类(尽管它们是可访问的),因此没有覆盖它的问题。即使您在子类中添加与其父类中相同的另一个静态方法,该子类静态方法也是唯一的,并且不同于其父类中的静态方法。
静态方法不能被覆盖,因为它们不是对象状态的一部分。相反,它们属于类(即它们是类方法)。可以重载静态(和最终)方法。
如果我通过使用SubClass名称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);
}
}
但是在方法重载的情况下,超类中的方法和子类中的方法充当不同的方法。超类将具有自己的副本,子类将具有自己的副本,因此不会受到方法覆盖。
重载也称为静态绑定,因此一旦使用单词static,就意味着静态方法无法显示运行时多态性。
我们无法覆盖静态方法,但是在超类及其子类中存在相同静态方法的不同实现是有效的。只是派生类将隐藏基类的实现。
对于静态方法,方法调用取决于引用的类型,而不取决于引用的对象,即静态方法仅属于类而不是其实例,因此,方法调用是在编译时自行决定的。
在方法重载的情况下,静态方法可以重载, 前提是它们具有diff数量或参数类型。如果两个方法具有相同的名称和相同的参数列表,则只能通过使用'static'关键字将它们定义为不同的值。
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
}
}
此示例覆盖静态方法
注意:如果我们使用对象引用调用静态方法,则将调用引用类型(类)静态方法,而不是对象类静态方法。
静态方法仅属于类。
不可以,您不能覆盖静态方法。静态对象针对类而不是实例进行解析。
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的所有内容仅属于该类,例如static方法不能在子类中继承,因为它们属于声明它们的类。引用静态关键字。
我发现这个问题的最佳答案是:
http://www.geeksforgeeks.org/can-we-overload-or-override-static-methods-in-java/
覆盖取决于拥有类的实例。多态性的重点是您可以对一个类进行子类化,并且实现那些子类的对象对于在超类中定义的相同方法(在子类中被重写)将具有不同的行为。静态方法不与类的任何实例关联,因此该概念不适用。
影响Java设计的因素有两个。一个是对性能的关注:Smalltalk对其速度太慢提出了很多批评(垃圾回收和多态调用是其中的一部分),Java的创建者决心避免这种情况。另一个决定是Java的目标受众是C ++开发人员。使静态方法按其实际方式工作对C ++程序员来说是个好处,而且速度非常快,因为不需要等到运行时就确定要调用哪个方法。