精华内容
下载资源
问答
  • Java中static方法为什么不能重写

    本篇博客来验证一下Java中static方法能不能被重写。

    首先,我们先来看一下多态的效果

    class People {
        public void buyTicket() {
            System.out.println("成人买票,全价!");
        }
    }
    
    class Student extends People {
        @Override
        public void buyTicket() {
            System.out.println("学生买票,半价!");
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            People[] peoples = {
                    new People(),
                    new Student()
            };
    
            for (People people : peoples) {
                buyTickets(people);
            }
        }
    
        private static void buyTickets(People people) {
            people.buyTicket();
        }
    }
    

    运行结果如下
    在这里插入图片描述

    下面,我们试着把People和Student中的buyTicket()方法改为静态方法

    class People {
        public static void buyTicket() {
            System.out.println("成人买票,全价!");
        }
    }
    
    class Student extends People {
        @Override
        public static void buyTicket() {
            System.out.println("学生买票,半价!");
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            People[] peoples = {
                    new People(),
                    new Student()
            };
    
            for (People people : peoples) {
                buyTickets(people);
            }
        }
    
        private static void buyTickets(People people) {
            people.buyTicket();
        }
    }
    

    我们来编译一下
    在这里插入图片描述
    可以看到重写父类中的static方法失败了

    但其实上述编译失败并不是因为不能重写父类中的static方法。首先我们要知道重写是为了什么?

    • 我们知道重写是实现多态的前提,在Java语法中允许子类出现和父类只有方法体不同其他都一模一样的static方法,但是在父类引用指向子类对象时,通过父类引用调用的依然是父类的static方法,而不是子类的static方法
    • 语法上支持对static方法的重写,但是运行效果上无法达到多态的目的
    • 上述的报错是因为@Override注解检查到buyTicket()方法在逻辑上达不到重写的目的,所以报错了。

    我们将@Override注解去掉,看一下运行效果:

    class People {
        public static void buyTicket() {
            System.out.println("成人买票,全价!");
        }
    }
    
    class Student extends People {
        public static void buyTicket() {
            System.out.println("学生买票,半价!");
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            People[] peoples = {
                    new People(),
                    new Student()
            };
    
            for (People people : peoples) {
                buyTickets(people);
            }
        }
    
        private static void buyTickets(People people) {
            people.buyTicket();
        }
    }
    

    在这里插入图片描述
    可以看到,和我们预期的一样,无法达到多态的效果

    展开全文
  • static方法为什么不能重写? 一. 重写的目的是什么 首先,重写的效果是什么:对于相同的方法,子类和父类要具有不同的行为,这使得子类的功能较父类来说有一定的扩展。但仅仅是扩展这么简单吗? 这种效果使得...

    static的方法为什么不能被重写?

    一. 重写的目的是什么

    1. 首先,重写的效果是什么:对于相同的方法,子类和父类要具有不同的行为,这使得子类的功能较父类来说有一定的扩展。但仅仅是扩展这么简单吗?
    2. 这种效果使得重写允许了多态的实现,重写是多态实现的前提(之一)。即当一个父类的对象实际上引用了子类对象时,向该对象发送消息调用方法时,实际上调用的是子类重写过的方法。这才是重写的主要作用,而不是简单扩展。如果你一直使用一个子类的对象调用某个方法的话,那么子类和父类中的方法完全可以没有任何关系重写使得子类和父类中相同的方法有所联系,而且子类和父类对于相同的方法具有不同的行为。
    3. 说到这了,重写是一个什么样的概念?
      • 它针对于相同的方法
      • 子类和父类中相同的方法要有所联系。
      • 虽然有所联系,但是子类和父类对于该相同的方法要有不同的行为。
      • 重写帮助实现了多态。

    二. 再说说多态、重写与static

    1. 多态的本质是什么?

      late binding。即运行的时候再去确定实际使用的对象类型是什么,进而确定实际上调用的方法是哪个。

    2. 所以可以看出多态的实现是一定要依赖于对象存在的。那么进而我们就可以认为,重写也要依赖于对象实例。

    3. static方法随着类加载而加载的,它只跟类相关,而与对象无关。所以它并不适用于上面讨论的概念。

    4. Overriding depends on having an instance of a class. The point of polymorphism is that you can subclass a class and the objects implementing those subclasses will have different behaviors for the same methods defined in the superclass (and overridden in the subclasses). A static method is not associated with any instance of a class so the concept is not applicable.

      重写依赖于存在类的某一实例。多态的要点在于你可以使一个类成为一个类的子类,并且对于在子类、父类中相同的方法(在子类中重写过),这些子类的对象将拥有不同的行为。一个静态的方法不会联系到任何实例上,所以这个概念并不适用。

    三. 说明与注意事项

    1. 静态方法可以被继承,但是,不能被覆盖,即重写。如果父类中定义的静态方法在子类中被重新定义,那么在父类中定义的静态方法将被隐藏。可以使用语法:父类名.静态方法调用隐藏的静态方法。
    2. 如果父类中含有一个静态方法,且在子类中也含有一个返回类型、方法名、参数列表均与之相同的静态方法,那么该子类实际上只是 将父类中的该同名方法进行了隐藏,而非重写。 换句话说,父类和子类中含有的其实是两个没有关系的方法,它们的行为也并不具有多态性。
    3. 因此,通过一个指向子类对象的父类引用变量来调用父子同名的静态方法时,只会调用父类的静态方法。
    4. 所以父类和子类中同名同参数的方法:要么全声明成static的【不考虑重写】;要么全声明成static的【考虑重写】
    展开全文
  • 我很困惑为什么不允许以下内容:public interface MyInterface {MyInterface getInstance(String name);}public class MyImplementation implements MyInterface {public MyImplementation(String name) {}@...

    我很困惑为什么不允许以下内容:

    public interface MyInterface {

    MyInterface getInstance(String name);

    }

    public class MyImplementation implements MyInterface {

    public MyImplementation(String name) {

    }

    @Override

    public static MyInterface getInstance(String name) { // static is not allowed here

    return new MyImplementation(name)

    }

    }

    我理解为什么接口中的方法不能是静态的,但是为什么重写方法不能是静态的?

    我希望所有类都实现getInstance(String name)方法,但是目前我只限于在对象已经被实例化的情况下调用该方法,哪种方法会破坏目标…

    *更新:*谢谢你的回答,我现在更理解了。基本上,我不应该试图让一个实用程序类(或者工厂类)实现一个接口(或者至少,不是这样的)。

    考虑一下,您将如何调用重写的静态方法?

    为什么Java不允许重写静态方法?(或者我为什么不能在接口中声明静态方法?)

    @从技术上讲,泰德霍普恰恰相反。

    这不是关于接口方法是静态的,而是允许我使实现方法是静态的。所以我可以叫MyImplementation.getInstance("foo");,而不是new MyInterface("foo").getInstance("foo");

    您试图不符合继承和静态方法。Java是否支持不一致继承?

    注意,在您的示例中,静态重写的签名与接口方法的签名不匹配。这甚至不是有效的覆盖。

    调用Java中的静态方法需要指定确切的类型。不可能以多态方式调用静态方法,从而消除了对@Override的需求。

    请注意,这种方法并不是所有语言都通用的:例如,您可以重写Objective-C中的类方法,而Apple的Cocoa框架很好地利用这种机制来定制它们的"工厂"类。然而,在爪哇中,C++和C类类方法不支持多态行为。

    从理论上讲,Java设计器可以让您通过EDCOX1、1个方法提供接口方法实现,以防实现不需要从实例访问状态。但是使用一个普通的包装器也很容易实现相同的行为:

    public class MyImplementation implements MyInterface {

    public MyImplementation(String name) {

    }

    @Override

    public MyInterface getInstance() { // static is not allowed here

    return getInstanceImpl();

    }

    public static getInstanceImpl() {

    return new MyImplementation(name)

    }

    }

    Java编译器可以为你做同样的事情,但是看到一个静态方法实现一个实例方法是既不寻常又令人困惑的,所以我猜想Java设计者决定不提供这个"魔术"。

    +一提到这不是普遍现象。Java调用语法使得这种方法不可能,而不是理论边界。

    静态方法不能受制于多态行为。那没什么意义。想象一下这个用例,假设您想要的是可能的:

    public void foo(MyInterface i) {

    i.getInstance("abc");

    }

    现在我想用MyInterface的实现(class A来调用这个方法,但是由于我不能传递类本身,所以需要传递一个对象:

    A a = new A();

    foo(a);

    现在在foo内部,对getInstance的static重写被类A的实例调用。所以现在我只能创建一个对象来调用静态方法。

    我的观点是,在大多数多态性的用例中,您仍然需要被约束来创建一个对象,因为在最初的接口中,该方法是一个实例方法。

    "那没有多大意义":它会——而且它也会非常有用。问题是为什么没有实现:stackoverflow.com/question s/20291984/…。请参阅以下内容,了解如何调用这些重写

    答案归结为实现接口意味着什么。当一个类实现一个接口时,这意味着该类的每个实例都将响应接口中的每个方法。当您将该方法实现为静态方法时,可以在没有类实例的情况下调用该方法,但这并不能实现继承实现的承诺,即该方法可以在类的每个实例上调用。

    因为实现接口会使实现者成为接口的类型。这意味着实例需要有由类型定义的方法,而不是实例的类。

    换一种说法,

    public void mymethod

    public static void mymethod

    不是相同的方法声明。它们是完全不同的。如果在接口上定义了mymethod,那么第二个定义就不能满足实现接口的要求。

    展开全文
  • “static”关键字是什么意思?static这个关键字表明当前这个这个方法或者...java中静态方法为什么不能重写?首先宏观的说:是因为非静态的方法是基于运行时动态绑定的,而static方法则是编译时静态绑定的。细致点...

    “static”关键字是什么意思?

    static这个关键字表明当前这个这个方法或者属性是属于类的。在类加载的时候就随着加载进内存、所有的对象都共享同一份的静态变量或者静态方法。static关键字修饰的属性和方法,可以直接通过    类名.属性名(方法名) 进行访问。


    java中静态方法为什么不能重写?

    首先宏观的说:是因为非静态的方法是基于运行时动态绑定的,而static方法则是编译时静态绑定的。

    细致点说:静态方法是类在加载到内存中的方法,在这呢各个运行过程中爆出不变,因而不能重写。但是非静态方法是在对象实例化的时候才单独申请内存空间,为每一个实例分配独立的运行内存,因而可以重写。

    展开全文
  • 我听说静态方法和private方法不能被覆盖,但是我试了一下以下代码,都能通过:public class A{ static void m(){ ...........} } class B extends A{ void m(){ ...........} } 或 public class ...
  • 在Java中调用静态方法需要您指定确切的类型.无法以多态方式调用静态方法,因此无需@Override.请注意,这种方法并非在所有语言中都是...从理论上讲,Java设计人员可以让您通过静态方法提供接口方法实现,以防实现需要从...
  • 静态的方法可以被继承,但是不能重写。如果父类中有一个静态的方法,子类也有一个与其方法名,参数类型,参数个数都一样的方法,并且也有static关键字修饰,那么该子类的方法会把原来继承过来的父类的方法隐藏,而...
  • 今天我们谈谈为什么抽象类中不能有静态的抽象方法以及static修饰的方法不能重写可以被继承 1 static修饰的方法不能重写可以被继承 我们知道static修饰的方法为静态方法,可以直接使用类名.方法名进行调用,即该...
  • 今天我们谈谈为什么抽象类中不能有静态的抽象方法以及static修饰的方法不能重写可以被继承 1 static修饰的方法不能重写可以被继承 我们知道static修饰的方法为静态方法,可以直接使用类名.方法名进行调用...
  • java为什么不能重写静态方法问题链接Question: Why is it not possible to override static methods? If possible, please use an example. Answer: Overriding depends on having an instance of a class. The...
  • 所以在子类中重写父类的私有方法的时候不能加上重写的注解,因为无法访问到父类的私有方法重写父类的私有方法相当于在子类中添加子类特有的方法,所以不能称之为重写。下面是详细的例子 public class Student ...
  •  Java中用static修饰符修饰的方法静态方法,下面讲一下static修饰的方法的用法以及特点.Java中static修饰的方法属于整个类的类方法,而不用static修饰的方法是属于某个具体类对象的方法,static方法使用...
  • 因为静态方法只与类相关,与具体实现相关,声明的是什么类,则引用相应类的静态方法(本来静态无需声明,可以直接引用),看下例子: Java代码 class Base{ static void a( ){System.out.println("A...
  • 在父类中是public的方法,如果子类中将其降低访问权限private, 那么父类在实现多态时如果调用子类的这个重写方法,但是这个方法已经是private,没有办法调用,所以就无法实现多态了。 public class Test { ...
  • 1.子类继承父类后,可以直接调用父类的变量和方法,那为什么还用super调用呢? 原因:如果子类对父类的变量和方法进行了重写,你又想再使用父类的方法,这是就需要super来调用,否则默认调用你在子类中重写的变量和...
  • 1、定义什么是静态变量:从面向对象的角度触发,当需要一个数据对象整类而非某个对象服务,同时又力求破坏类的封装性;既要求此成员隐藏在类的内部,又要求对外可见的时候,就可以使用static。2、作用(1)函数...
  • 1.abstract与private一起使用,相互矛盾 abstract修饰的方法是要给子类重写,private修饰的方法只能本类访问。 2.abstract与static一起使用,无意义 abstact修饰的方法是抽象的...final修饰方法不让子类重写,而ab...
  • abstract 不能用来修饰私有方法,静态方法,final修饰的类...不能修饰static修饰的方法:因为静态方法表示可以直接用类名调用此方法,abstract修饰的方法没有方法体,所属类类必定是一个抽象类,不能实例化,必须让子类去重写,
  • 接口实现方法,static是静态调用,调用实现的方法,有意义吗?接口里的方法是通过接口映射表来调用实现的(vmt),用virtual没有意义..接口里实现方法,自然override重写就没意义了..接口是全部抽象的,既然全都是抽象,...
  • 重写方法 重写:需要有继承关系,子类重写父类的方法! 1.方法名必须相同 2.參数列表列表必须相同 3… 修饰符:范围可以扩大但不能...为什么需要重写: 1.父类的功能,子类不一定需要,或者不一-定满足! Alt + Insert ; o
  • 我的理解static和普通方法是在不同内存的,当子类重写为方法添加static时,jvm根本搞清楚调用哪个 一直半解在网上搜到了一个前辈说的。我觉得挺深刻的覆盖(override)是在继承+多态的前提下的概念。Java中的...
  • 答:首先静态属性和静态方法是可以被子类继承的,但静态属性不能被子类重写重写的本质是动态绑定,即根据运行时对象的类型来决定调用哪个方法,而不是根据编译时的类型。静态方法属于类的,在编译阶段已经静态...
  • public class TestA { public static void main(String[] args) { TestA a = new TestA();...我就是想问为什么调用父类方法后,父类为什么调用的是子类的方法,不是调用抽象么,抽象不是不能被调用么
  • 重写 重写:需要有继承关系,子类重写父类的方法! 1、方法名必须相同 2、参数列表必须相同 3、修饰符:范围可以扩大,不能缩小 public>...为什么需要重写: 1、父类的功能,子类不一定需要,或者不

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 162
精华内容 64
关键字:

为什么static方法不能重写