zoukankan      html  css  js  c++  java
  • 方法覆盖

    1 方法覆盖
        1.1 什么时候考虑方法覆盖?
            父类中的方法无法满足子类的业务需求,子类有必要对继承过来的方法进行覆盖。
            
        1.2 什么条件 满足的时候构成方法覆盖?
            第一:有继承关系的两个类。
            第二:具有相同方法名、返回值类型、形式参数列表。
            第三:访问权限不能更低。
            第四:抛出异常不能更多。
            
            
        1.3 关于Object类中toString()方法的覆盖?
            toString()方法存在的作用就是:将java对象转换成字符串形式。
            大多数的java类的toString()方法都是需要覆盖的。因为Object类中提供的toString()方法输出的是一个java对象的内存地址。
            
            至于toString()方法具体怎么进行覆盖?
                格式可以自己定义,或者听需求的。(听项目要求的。)
                
        1.4 方法重载和方法覆盖有什么区别?
            方法重载发生在同一个类当中。
            方法覆盖是发生在具有继承关系的父子类之间。
            
            方法重载是一个类中,方法名相同,参数列表不同。
            方法覆盖是具有据称关系的父子类,并且重写之后的方法必须和之前的方法一致:
                方法名一致、参数列表一致、返回值类型一致。
     
     
     
    案例1:
    /*
        当前程序存在的问题(设计上的问题)????
            鸟儿在执行move()方法的时候,最好输出的结果是:“鸟儿在飞翔”
            但是当前的程序在执行move() 方法的时候输出的结果是:“动物在移动”!
            很显然Bird子类从Animal父类中继承过来的move()方法已经无法满足子类的业务需求。
    */
    public class OverrideTest01{
        public static void main(String[] args){
            // 创建鸟儿的对象
            Bird b = new Bird();
            // 让鸟儿移动
            b.move();
            
            Cat c = new Cat();
            
            c.move();
        }
    }
    
    // 父类
    class Animal{
        // 但是有一些方法是需要覆盖的
        // 移动 实例方法
        public void move(){
            System.out.println("动物在移动!!!!");
        }
        
        // 这个方法可能不需要覆盖
        public void doSome(){
            
        }
    }
    // 子类
    class Bird extends Animal{
        
        // 子类继承父类中,有一些“行为”可能不需要改进,有一些“行为”可能面临着必须改进。
        // 因为父类中继承过来的方法已经无法满足子类的业务需求
        
        // 鸟儿在移动的时候希望输出鸟儿在飞翔!!!!
    }
    
    class Cat extends Animal{
        // 猫在移动的时候,我希望输出:猫在走猫步!!!!!
    }

    案例2:

    /*
        回顾一下方法重载!!!!
            什么时候考虑使用方法重载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(){
        protected void move() throws Exception{// 这样就可以
            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("鸟儿在飞翔!!!!");
        }
        
        // 错误: Bird中的move()无法覆盖Animal中的move()
        // 被覆盖的方法未抛出Exception
        /*
        public void move() throws Exception {
            System.out.println("鸟儿在飞翔!!!!");
        }
        */
        
        // protected表示受保护的。没有public开放。
        // 错误: Bird中的move()无法覆盖Animal中的move() 正在尝试分配更低的访问权限; 以前为public
        /*
        protected void move(){
            System.out.println("动物在移动!");
        }
        */
        
        // 分析:这个sing方法和父类中的sing(int i)发生了方法的重写了吗?
        // 没有,原因是:这两个方法根本就是两个完全不同的方法。
        // 可以说这两个方法构成了方法重载吗?可以。
        public void sing(){
            System.out.println("move sing......");
        }
    }
    
    class Cat extends Animal{
        // 方法重写(重新编写)
        public void move(){
            System.out.println("猫儿在走猫步!!!!");
        }
    }



    比较经典的方法覆盖案例:

    /*
        方法覆盖比较经典的案例
        一定要注意:方法覆盖/重写的时候,建议将父类的方法复制黏贴,这样比较保险。
    */
    public class OverrideTest03{
        public static void main(String[] args){
            // 创建中国人对象
            ChinaPeople c = new ChinaPeople();
            c.setName("张三");
            c.speak();
            // 创建美国人对象
            AmericPeople a = new AmericPeople();
            a.setName("lisi");
            a.speak();
        }
    }
    
    //
    class People{
        
        // 属性
        private String name;
        
        // 构造方法
        public People(){}
        public People(String name){
            this.name = name;
        }
        // getter and setter
        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(this.getName() + " speak english");
        }
    }

    覆盖Object中toString()方法案例:

    public class OverrideTest04{
        public static void main(String[] args){
            // 创建日期对象
            MyDate date = new MyDate();
            // 调用toString()方法(将对象转换成字符串形式。)
            
            // 问:你对这个输出结果满意吗?不满意  希望输出xx年xx月xx日
            // 什么时候需要使用方法覆盖????
            // System.out.println(date.toString());// MyDate@54bedef2
            
            // 重写MyDate的toString() 方法之后的结果
            System.out.println(date.toString());
            
            // 大家是否还得:当输出一个引用的时候,println方法会自动调用引用的toString方法。
            System.out.println(date);
            
            MyDate date2 = new MyDate(2008,8,8);
            System.out.println(date2);
            
        }
    }
    
    class MyDate{// 如果你不继承的话 默认继承的是Object
        // 封装私有属性
        private int year;
        private int month;
        private int day;
        
        // 构造函数
        public MyDate(){
            this(1970,1,1);    
        }
        public MyDate(int year,int month,int day){
            this.year = year;
            this.month = month;
            this.day = day;
        }
        
        // getter and setter
        public void setYear(int year){
            this.year = year;
        }
        
        public int getYear(){
            return year;
        }
        
        public void setMonth(int Month){
            this.month = month;
        }
        
        public int getMonth(){
            return month;
        }
        
        public void setDay(int day){
            this.day = day;
        }
        
        public int getDay(){
            return day;
        }
        
        // 从Object类中继承过来的那个toString() 方法已经无法满足我业务需求了。
        // 我在子类MyDate中有必要对父类的toString()方法进行覆盖/重写。
        // 我的业务要求是:调用toString()方法进行字符串的时候,希望转换的结果是:xxxx年xx月xx日,这种格式。
        // 重写一定要赋值黏贴,不要手动编写,会错的。
        
        public String toString(){
            return year + "年" + month + "月" + day + "日";
        }
    }
    
    // 多态机制:多态的存在让程序具有很强的扩展性。
  • 相关阅读:
    LeetCode Subsets II
    LeetCode Rotate Image
    LeetCode Palidrome Number
    LeetCode Generate Parentheses
    LeetCode Maximum Subarray
    LeetCode Set Matrix Zeroes
    LeetCode Remove Nth Node From End of List
    Linux Loop设备 使用
    Linux 文件系统大小调整
    LeetCode N-Queens II
  • 原文地址:https://www.cnblogs.com/xlwu/p/13062236.html
Copyright © 2011-2022 走看看