Java中方法覆盖与多态

这是我参与11月更文挑战的第 13 天,活动详情查看:2021最后一次更文挑战

怎么进行方法覆盖

理解方法覆盖之前,我们回顾一下方法重载(Overload),什么情况下考虑使用方法的重载呢?带着同样的疑问,怎么进行方法的覆盖呢?请看如下代码进行体会:

public class People{
    private String name;
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name=name;
    }
    public void speakHi(){
        System.out.println(this.name+"和别人打招呼!");
    }
}

public class ChinaPeople extends People{
    public void speakHi(){
        System.out.println("你好,我叫"+this.getName()+",很高兴认识你!");
    }
}

public class AmericaPeople extends People{
    public void speakHi(){
        System.out.println("Hi,My name is"+this.getName()+"Nice to meet you!");
    }
}

public class PeopleTest{
    public static void main(String[] args){
        ChinaPeople cp=new ChinaPeople();
        cp.setName("张三");
        cp.speakHi();
        AmericaPeople ap=new AmericaPeople();
        ap.setName("jackson");
        ap.speakHi();
    }
}

//程序运行结果如下:
你好,我叫张三,很高兴认识你!
Hi,My name is jackson,Nice to meet you!
复制代码

通过以上的代码学习,我们了解到只有当从父类中继承过来的方法无法满足当前子类业务需求的时候,需要将父类中继承过来的方法进行覆盖。换句话说,父类中继承过来的方法已经不够用了,子类有必要将这个方法重新再写一遍,所以方法覆盖又称为重写。当该方法被重写之后,子类对象一定会调用重写之后的方法。

方法覆盖的条件

那么,当程序具备哪些条件的时候,就能构成方法覆盖呢?

  • 1,方法覆盖发生在具有继承关系的父子类之间,这是首要条件;

  • 2,覆盖之后的方法与原方法具有相同的返回值类型、相同的方法名、相同的形式参数列表;

方法覆盖的注意事项

另外,在使用方法覆盖的时候,需要有哪些注意事项呢?

  • 1,由于覆盖之后的方法与原方法一模一样,建议在开发的时候采用复制粘贴的方式,不建 议手写,因为手写的时候非常容易出错,比如在 Object 类当中有 toString()方法,该方法中的 S 是大写的,在手写的时候很容易写成小写 tostring(),这个时候你会认为 toString()方法已经 被覆盖了,但由于方法名不一致,导致最终没有覆盖,这样就尴尬了;

  • 2,私有的方法不能被继承,所以不能被覆盖;

  • 3,构造方法不能被继承,所以也不能被覆盖;

  • 4,覆盖之后的方法不能比原方法拥有更低的访问权限,可以更高(学习了访问控制权限修 饰符之后你就明白了);

  • 5,覆盖之后的方法不能比原方法抛出更多的异常,可以相同或更少(学习了异常之后就明 白了);

  • 6,方法覆盖只是和方法有关,和属性无关;

  • 7,静态方法不存在覆盖(不是静态方法不能覆盖,是静态方法覆盖意义不大,学习了多态 机制之后就明白了);

总结

当父类继承过来的方法无法满足当前子类业务需求的时候,子类有必要将父类中继承过来的方法进行覆盖/重写。方法覆盖发生在具有继承关系的父子类之间,方法覆盖的时候要求相同的返回值类型、相同的方法名、相同的形式参数列表。方法覆盖之后子类对象在调用的时候一定会执行覆盖之后的方法。

多态基础语法

多态(Polymorphism)属于面向对象三大特征之一,它的前提是封装形成独立体,独立体之间存在继承关系,从而产生多态机制。多态是同一个行为具有多个不同表现形式或形态的能力。

在Java 中允许这样的两种语法出现,一种是向上转型(Upcasting),一种是向下转型(Downcasting),向上转型是指子类型转换为父类型,又称为自动类型转换,向下转型是指父类型转换为子类型,又称为强制类型转换。

Java 中规定,无论向上转型还是向下转型,两种类型之间必须要有继承关系,没有继承关系情况下进行向上转型或向下转型的时候编译器都会报错。

看如下代码进行体会:

public class Animal{
    public void move(){
        System.out.println("Animal move!");
    }
}

public class Cat extends Animal{
    //方法覆盖
    public void move(){
        System.out.println("走猫步!");
    }
    //子类特有
    public void catchMouse(){
        System.out.println("抓老鼠!");
    }
}

public class Bird extends Animal{
    //方法覆盖
    public void move(){
        System.out.println("鸟儿在飞翔!");
    }
    //子类特有
    public void sing(){
        System.out.println("鸟儿在唱歌!");
    }
}

public class Test01{
    public static void main(String[] args){
        //创建Animal对象
        Animal a=new Animal();
        a.move();
        //创建Cat对象
        Cat c=new Cat();
        c.move();
        //创建鸟儿对象
        Bird b=new Bird();
        b.move;
    }
}

//运行结果如下:
Animal move!
走猫步!
鸟儿在飞翔!
复制代码

以上程序演示的就是多态,多态就是“同一行为(move)”作用在“不同的对象上”会有不同的表现结果。

多态与覆盖的联系

其实多态有三个必要的条件分别是:

  • 1,继承
  • 2,方法覆盖
  • 3,父类型引用指向子类型对象

多态显然是离不开覆盖机制的,多态就是因为编译阶段绑定父类当中的方法,程序运行阶段自动调用子类对象上的方法,如果子类对象上的方法没有进行重写,这个时候创建子类对象就没有意义了,自然多态也就没有了意义,只有子类将方法重写之后调用到子类对象上的方法产生不同效果时,多态就形成了。

多态在开发中的作用

以上我们知道了多态的基础语法,多态在实际开发中有什么作用呢?

多态在开发中联合方法覆盖一起使用,可以降低程序的耦合度, 提高程序的扩展力。 在开发中尽可能面向抽象编程,不要面向具体编程,好比电脑主板和内存条的关系一样,主板和 内存条件之间有一个抽象的符合某个规范的插槽,不同品牌的内存条都可以插到主板上使用,2个G 的内存条和4 个G 的内存条都可以插上,但最终的表现结果是不同的,2 个G的内存条处理速度慢一些, 4个G的快一些,这就是多态,所谓多态就是同一个行为作用到不同的对象上,最终的表现结果是不同的, 主要的要求就是对象是可以进行灵活切换的,灵活切換的前提就是解耦合,解耦合依赖多态机制。

这里只能做一个笼统的概述,具体还得我们在代码中体会。

猜你喜欢

转载自juejin.im/post/7035573656960892935