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 + "日";
        }
    }
    
    // 多态机制:多态的存在让程序具有很强的扩展性。
  • 相关阅读:
    js几个常用的弹层
    ubuntu 更新源 或者 apt-get install 出错404 not found ,Failed to fetch
    vmware ubuntu 解决 宿主机与虚拟机互相ping不通,虚拟机无线上网的解决办法
    mediawiki资料
    mediawiki问题
    JavaEE异常
    前端网站收藏
    依赖注入--setting注入和构造器注入
    Spring注入Bean
    Spring简介
  • 原文地址:https://www.cnblogs.com/xlwu/p/13062236.html
Copyright © 2011-2022 走看看