方法覆盖

96 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情

哈喽,大家好!我是Why,一名在读学生,目前刚刚开始进入自己的编程学习生涯。虽然学习起步较晚,但我坚信做了才有0或1的可能。学了一段时间以后也是选择在掘金上分享自己的日常笔记,也希望能够在众多道友的大家庭中打成一片。 本文主要讲解方法覆盖,如果大家读后觉得有用的话,还请大家多多支持博主:欢迎 ❤️点赞👍、收藏⭐、留言💬 ✨✨✨个人主页:JinHuan

方法覆盖

使用时机

 子类从父类中继承过来的方法已经无法满足子类的业务需求

栗子

 ​
 /*
     当前程序存在的问题(设计上的问题)????
         鸟儿在执行move()方法的时候,最好输出的结果是:“鸟儿在飞翔”
         但是当前的程序在执行move()方法的时候输出的结果是:"动物在移动!"
         很显然Bird子类从Animal父类中继承过来的move()方法已经无法满足子类的业务需求。
 ​
 */
 public class OverrideTest01{
     public static void main(String[] args){
         // 创建鸟对象
         Bird b = new Bird();
         // 让鸟儿移动
         b.move();
 ​
         // 创建Cat类型对象
         Cat c = new Cat();
         c.move();
     }
 }
 ​
 // 父类 
 class Animal{
 ​
     // 移动
     public void move(){
         System.out.println("动物在移动!");
     }
 ​
 }
 ​
 // 子类
 class Bird extends Animal{
 ​
     // 子类继承父类中,有一些“行为”可能不需要改进,有一些“行为”可能面临着必须改进。
     // 因为父类中继承过来的方法已经无法满足子类的业务需求。
 ​
     // 鸟儿在移动的时候希望输出鸟儿在飞翔!!!!
 }
 ​
 class Cat extends Animal{
     // 猫在移动的时候,我希望输出:猫在走猫步!!!!!!
 }

方法覆盖与方法重载

 /*
     回顾一下方法重载!!!!
         什么时候考虑使用方法重载overload?
             当在一个类当中,如果功能相似的话,建议将名字定义的一样,这样
             代码美观,并且方便编程。
         
         什么条件满足之后能够构成方法重载overload?
             条件一:在同一个类当中
             条件二:方法名相同
             条件三:参数列表不同(个数、顺序、类型)
 ​
     --------------------------------------------------------------------------------
 ​
     什么时候我们会考虑使用“方法覆盖”呢?
         子类继承父类之后,当继承过来的方法无法满足当前子类的业务需求时,
         子类有权利对这个方法进行重新编写,有必要进行“方法的覆盖”。
     
     方法覆盖又叫做:方法重写(重新编写),英语单词叫做:Override、Overwrite,都可以。
     比较常见的:方法覆盖、方法重写、override
 ​
     重要结论:
         当子类对父类继承过来的方法进行“方法覆盖”之后,
         子类对象调用该方法的时候,一定执行覆盖之后的方法。
 ​
     当我们代码怎么编写的时候,在代码级别上构成了方法覆盖呢?
         条件一:两个类必须要有继承关系。
         条件二:重写之后的方法和之前的方法具有:
                     相同的返回值类型、
                     相同的方法名、
                     相同的形式参数列表。
         条件三:访问权限不能更低,可以更高。(这个先记住。)
         条件四:重写之后的方法不能比之前的方法抛出更多的异常,可以更少。(这个先记住)
     
     这里还有几个注意事项:(这几个注意事项,当学习了多态语法之后自然就明白了!)
         注意1:方法覆盖只是针对于方法,和属性无关。
         注意2:私有方法无法覆盖。
         注意3:构造方法不能被继承,所以构造方法也不能被覆盖。
         注意4:方法覆盖只是针对于“实例方法”,“静态方法覆盖”没有意义。
 ​
 */
 public class OverrideTest02{
     public static void main(String[] args){
         Bird b = new Bird();
         b.move();
         b.sing(1000); //Animal sing....
 ​
         Cat c = new Cat();
         c.move();
     }
 }
 ​
 class Animal{
     public void move(){
         System.out.println("动物在移动!");
     }
 ​
     public void sing(int i){
         System.out.println("Animal sing....");
     }
 }
 ​
 class Bird extends Animal{
 ​
     // 对move方法进行方法覆盖,方法重写,override
     // 最好将父类中的方法原封不动的复制过来。(不建议手动编写)
     // 方法覆盖,就是将继承过来的那个方法给覆盖掉了。继承过来的方法没了。
     public void move(){
         System.out.println("鸟儿在飞翔!!!");
     }
 ​
     //protected表示受保护的。没有public开放。
     // 错误:正在尝试分配更低的访问权限; 以前为public
     /*
     protected void move(){
         System.out.println("鸟儿在飞翔!!!");
     }
     */
 ​
     //错误:被覆盖的方法未抛出Exception
     /*
     public void move() throws Exception{
         System.out.println("鸟儿在飞翔!!!");
     }
     */
 ​
     // 分析:这个sing()和父类中的sing(int i)有没有构成方法覆盖呢?
     // 没有,原因是,这两个方法根本就是两个完全不同的方法。
     // 可以说这两个方法构成了方法重载吗?可以。
     public void sing(){
         System.out.println("Bird sing.....");
     }
 }
 ​
 class Cat extends Animal{
 ​
     // 方法重写
     public void move(){
         System.out.println("猫在走猫步!!!");
     }
 }

方法重载经典案例

 //方法覆盖比较经典的案例
 //一定要注意:方法覆盖/重写的时候,建议将父类的方法复制粘贴,这样比较保险。
 public class OverrideTest03{
     public static void main(String[] args){
         // 创建中国人对象
         // ChinaPeople p1 = new ChinaPeople("张三");// 错误原因:没有这样的构造方法
         ChinaPeople p1 = new ChinaPeople();
         p1.setName("张三");
         p1.speak();
 ​
         // 创建美国人对象
         // AmericPeople p2 = new AmericPeople("jack"); // 错误原因:没有这样的构造方法
         AmericPeople p2 = new AmericPeople();
         p2.setName("jack");
         p2.speak();
     }
 }
 ​
 // 人
 class People{
     // 属性
     private String name;
     // 构造
     public People(){}
     public People(String name){
         this.name = name;
     }
     //setter and getter
     public void setName(String name){
         this.name = name;   
     }
     public String getName(){
         return name;
     }
     // 人都会说话
     public void speak(){
         System.out.println(name + "....");
     }
 }
 ​
 // 中国人
 class ChinaPeople extends People{
 ​
     // 中国人说话是汉语
     // 所以子类需要对父类的speak()方法进行重写
     public void speak(){
         System.out.println(this.getName() + "正在说汉语");
     }
 }
 ​
 ​
 // 美国人
 class AmericPeople extends People{
     // 美国人说话是英语
     // 所以子类需要对父类的speak()方法进行重写
     public void speak(){
         System.out.println(getName() + " speak english!");
     }
 }
 ​