Java中的方法重写

Java中的方法重写,java,overriding,Java,Overriding,方法重写是如何在Java中实现的?在C++中,我们有VTHT的概念。这在Java内部是如何实现的?只要您希望重写的函数(方法)没有标记为final,您只需通过扩展持有该方法的类来重写该方法,然后提供具有相同签名但不同主体的方法。要回答这个问题,这是在虚拟机中实现重写的具体方式,在(谷歌图书链接)中有一篇文章 VM将在引用的类中查找适当的方法定义,然后通过继承堆栈向上运行。显然,在某些阶段,各种优化将适用 有关相关字节码指令的说明,请参见: invokevirtual查看描述符 在中给出,并确定

方法重写是如何在Java中实现的?在C++中,我们有VTHT的概念。这在Java内部是如何实现的?

只要您希望重写的函数(方法)没有标记为
final
,您只需通过扩展持有该方法的类来重写该方法,然后提供具有相同签名但不同主体的方法。

要回答这个问题,这是在虚拟机中实现重写的具体方式,在(谷歌图书链接)中有一篇文章

VM将在引用的类中查找适当的方法定义,然后通过继承堆栈向上运行。显然,在某些阶段,各种优化将适用

有关相关字节码指令的说明,请参见:

invokevirtual查看描述符 在中给出,并确定 该方法需要多少个参数 (这可能是零)。它砰砰地响着 操作数堆栈中的参数。下一个 它从堆栈中弹出objectref。 objectref是对对象的引用 正在调用其方法。 invokevirtual检索Java类 用于objectref,并搜索列表 由该类和 然后它的超类,寻找一个 名为methodname的方法,其 描述符是描述符


正如gustafc在下面强调的那样,可以应用各种优化,毫无疑问JIT将进一步引入。

也许这是一个有趣的问题。

方法覆盖 这意味着super类中有一个方法可用,该方法显示一些字符串,但您希望扩展该类,同时还希望打印自己的方法,此时需要将该方法重写到本地类中。
这是覆盖的基本介绍

eg.
class Animal
{
  public void displayMessage()
  {
    System.out.println("Animal is eating");
  }

}
class Dog extends Animal
{
  public void displayMessage()
  {
    System.out.println("Dog is eating");
  }
  public static void main(String arg[])
  {
    Dog d=new Dpg();
    d.displayMessage();
  }
}
输出:

狗在听

方法重写的优点是,类ca将其自己的特定实现赋予继承的方法,而无需修改父类方法

方法重写的规则是

参数列表:参数列表必须相同。
访问修饰符:如果重写该方法,则必须为该方法指定与超级类方法相同的修饰符。假设超级类具有公共方法,则不能为受保护或私有方法指定修饰符……等等

Java中的方法重写是一个基于多态性OOPS的概念 允许程序员创建两个同名方法的概念 接口上的方法签名及其各种实现和应用 根据运行时对象的类型,在运行时调用实际方法 运行时。方法重写允许您编写灵活且可扩展的 使用Java编写代码,因为您可以以最少的成本引入新功能 代码更改

在Java中重写任何方法时,需要遵循的规则很少,不遵循这些规则会导致Java中的编译时错误

  • 关于Java中方法重写的第一条也是最重要的规则是,只能重写子类中的方法。不能重写同一类中的方法
  • Java中方法重写的第二个重要规则是,方法的名称和签名在超类和子类中或在接口及其实现中必须相同
  • Java中重写方法的第三条规则是重写方法不能降低Java中被重写方法的可访问性。例如,如果重写方法是公共的,则重写方法不能被保护、私有或包私有;但事实正好相反,重写方法可以增加Java中方法的可访问性,也就是说,若重写方法受到保护,则重写方法可以受到保护或公开
  • Java中方法重写的另一个值得注意的规则是,重写方法不能抛出层次结构中高于被重写方法的检查异常。这意味着,若重写方法抛出IOException,则重写方法不能在其throws子句中抛出java.lang.Exception,因为java.lang.Exception在异常层次结构中高于IOException。此规则不适用于Java中的RuntimeException,Java中甚至不需要在throws子句中声明RuntimeException
  • 您不能在Java中重写私有、静态和final方法。私有方法和静态方法在编译时使用Java中的静态绑定绑定,在运行时不解析。Java中重写最后一个方法的是编译时错误。尽管私有和静态方法可以隐藏,但若您在子类中声明另一个具有相同和签名的方法
  • 重写的方法是在Java中根据对象类型在运行时使用动态绑定调用的
  • 若要扩展抽象类或实现接口,则需要重写所有抽象方法,除非类不是抽象的。抽象方法只能通过使用方法重写来使用
  • 在Java中重写方法时始终使用@Override注释。虽然这不是规则,但它是最好的Java编码实践之一。在Java6中,您还可以对从接口继承的方法使用@Override注释

  • 回答者:OP特别询问Java中重写的实现(例如在编译器或JVM本身中),不是如何在代码中重写方法。记住,
    invokevirtual
    invokeinterface
    调用实际上可能导致内联代码-如果被调用方仅由一个加载的类实现,则无需搜索每个类的方法。如果有两个类实现了这些方法,则调用会被JIT成一个
    If
    /
    else
    检查对象的类型,这也比进行方法查找更快。虽然此代码可能会回答问题,但提供有关此代码为什么和/或如何回答问题的附加上下文会提高其长期价值。
    --Defining the same method with the same method signature(i.e. same number/type of arguments and same return type/s.)in base and derived class.
    --Which method is to be called is decided  at runtime so, it is also called runtime polymorphism/late binding. 
    --we should override the method defined in the superclass.
    --when the method is called the method defined in the subclass is called and executed instead of the one in superclass.
    --we overcome this by use of 'super' keyword.
    //program
    class A
    {
    void disp(){
    System.out.println("class A");
    }
    
    }
    class B extends A
    {
    public void disp(){
    System.out.println("class B");
    
    }
    }
    public class ExampleIdea{
    public static void main(String[] args){
    A a  = new B(); //Parent reference but B class object (we can achieve polymorphism when parent class reference is used to refer a child class object) 
    B b = new B();    //B class reference and B class object
    A c = new A();
    a.disp(); //runs the method in B class 
    b.disp();  //runs the method in B class
    c.disp();  //runs then method in A class
    }
    }//end of program
    
    when we run this output will be class B.
    
    In order to access the function of class A we have to use super keyword
    as:
    
     class B extends A
    {
    public void disp(){
    System.out.println("class B");
    super.disp();
    }