千家信息网

Java中重写和覆盖怎么用

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,小编给大家分享一下Java中重写和覆盖怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!关于类的重写和覆盖,我们很容易把
千家信息网最后更新 2025年02月02日Java中重写和覆盖怎么用

小编给大家分享一下Java中重写和覆盖怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

关于类的重写和覆盖,我们很容易把他们搞混淆,在Java中jvm会自动帮我们处理这样的问题,但是在c#中咱们也有相关的关键字和处理方式,我们先来研究一下继承关系中构造函数和方法的执行顺序问题。

下面我们来个简单的代码

class A{    public A()    {        Console.WriteLine("这是a构造函数");    }    public void a()    {        Console.WriteLine("这是a方法");    }}class B : A{    public B()    {        Console.WriteLine("这是b构造函数");    }    public void b()    {        Console.WriteLine("这是b方法");    }}
class Program{ static void Main(string[] args) { Console.WriteLine("创建父级==============================================="); A a = new A(); Console.WriteLine("创建子级==============================================="); B b = new B(); Console.WriteLine("父级开始调用a方法======================================"); a.a(); Console.WriteLine("子级开始调用b方法======================================"); b.b(); Console.WriteLine("创建一个像父级的子级==================================="); A a1 = new B(); a1.a(); Console.Read(); }}

输出如下

创建父级===============================================这是a构造函数创建子级===============================================这是a构造函数这是b构造函数父级开始调用a方法======================================这是a方法子级开始调用b方法======================================这是b方法创建一个像父级的子级===================================这是a构造函数这是b构造函数这是a方法

我们可以从上面的返回可以知道,在继承关系中,先执行父级的构造函数,然后是子级构造函数,然后再调用方法。

当然这里注意的是,需要一个父类可以给一个子类或者父类实例,但是反过来不可以,这个是我们后面学的多态,或者可以说是里氏代换原则。

覆盖

覆盖简单的来说就是子类继承父类,同时也继承了不为私有的成员,如果说子类有一个与父类同方法签名的方法,且没有被重写,那么我们在调用这个方法的时候由于父类的方法优先于子类的方法,子类被父类覆盖。

下面我们来看一段代码

class A{    public void a()    {        Console.WriteLine("这是父级a方法");    }}class B : A{    public void a()    {        Console.WriteLine("这是子级a方法");    }}
class Program{ static void Main(string[] args) { A a = new B(); a.a(); Console.Read(); }}
这是父级a方法

此时我们看到调用子类的方法时,被父类覆盖了,调用了父级的方法。

这里我们值得注意的是编译器已经出现了一处警告

那么在c#中,new关键字的另一种用法就是消除覆盖的警告

class B : A{    public new void a(){        Console.WriteLine("这是子级a方法");    }}

虽然我们加上这个new并没有改变执行结果,毕竟我们要达到"0 error,0 warning"

那么有些时候,我父级的一个方法就是为了给子类扩展自己这个方法的特别之处,比如鸟类有翅膀,子类的燕子既有翅膀还飞得贼快,子类鸵鸟虽然有翅膀但它不能飞。别人就说所有的鸟都能飞,那么我给一个鸵鸟给他是不是证明了他说的是错误的。

只要能用到父级的地方,我们都能够用他的子类来代替,因为子类包括父类的特征,这个就是我们面向对象原则里面的里氏代换原则。有些时候父级的一些方法不能实现我们想要的效果,那么我们就重写这个父类的这个方法。

重写

重写也是在父子继承关系中存在的,重写父级的方法用关键字virtual标记父级的方法,表示这个方法是一个虚方法(有些地方叫虚函数,都差不多),在子级用override重写父级标记的方法,这两个关键字是一起使用的。如果父级virtual标记了但是子级没有使用override重写,那是没有效果的,下面看代码:

class A{    public virtual void a()    {        Console.WriteLine("这是父级a方法");    }}class B : A{    public override void a()    {        Console.WriteLine("这是重写父级a方法");    }}class Program{    static void Main(string[] args)    {        A a = new B();        a.a();    }}
这是重写父级a方法

我们区分重写和覆盖,它真的非常重要,重写是面向对象中一个非常重要的基础。

总结:

覆盖:使用父类创建子类,由于父类的方法先执行,所有子类的方法被覆盖,使用关键字new来消除编译器的警告。

重写:父类的方法需要用virtual标记为虚方法,子类使用override重写父类的虚方法。使用父类对象创建一个子类对象代替,子类方法重写父类方法,每个子类都不一样,我们要灵活使用

以上是"Java中重写和覆盖怎么用"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

0