Java面向对象软件开发
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.3.2 重写

当同名方法同时存在于子类和父类中时,对于子类来说就是将继承的父类的方法重新写过了,实现功能完全可以和父类无关。当调用子类的方法时,运行的是子类重新改写的方法,而不是父类的方法。

例2-11】 重写方法的调用。

            class A {
                void display() {
                    System.out.println("这是父类的方法");
                }
                void print() {
                    System.out.println("A's method print() called!");
                }
            }
            class B extends A{           // 子类B派生自父类A
                void display(){         // 方法的重写
                    System.out.println("这是子类的方法");
                }
            }
            public class Test {
                public static void main(String args[]) {
                    A a1=new A();      //a1引用类A的实例
                    a1.display();
                    a1.print();
                    A a2=new B();      //a2引用类B的实例,子类对象可以看做父类对象
                    a2.display();
                    a2.print();
                }
            }

该程序的运行结果为:

            这是父类的方法
            A's method print() called!
            这是子类的方法
            A's method print() called!

Java运行时,系统分析是类A的一个实例还是类B的一个实例,以决定是调用类A的方法display()还是调用类B的方法display()。

特别提示:

方法的覆盖中需注意的是,子类在重写父类已有的方法时,应保持与父类完全相同的方法头声明,即应与父类有完全相同的方法名、返回值和参数列表。否则,就不是方法的覆盖,而是在子类定义自己的与父类无关的成员方法。

方法重写时要遵循三个原则:

(1)重写方法的返回类型必须与它所重写的方法相同。

(2)重写方法不能比它所重写的方法有更严格的访问权限,也就是子类private方法不能覆盖掉父类public的方法。

(3)重写方法不能比它所重写的方法抛出更多的异常。

进行方法重写时必须遵循这三个原则,否则编译器会指出程序出错。

工作分解-操作方案

1.分析抽象出类;

2.按照类图编制出类框架;

3.实现类方法;

4.创建对象;

5.调用对象中的方法完成具体功能。

工作实施

1.分析抽象出类

从本任务中,我们可以分析出共有三个类:People(人)类是父类,Student(学生)类和Teacher(教师)类都是People类的子类。People类有两个非私有属性:姓名name和年龄age;四个成员方法:一个无参构造方法(用于将属性初始化为其默认值),一个带参构造方法,一个表示“人”说话行为的方法talk(),以及表示“人”工作行为的方法work()。Student类除了从父类People继承的成员外还新增了一个属性:学号sNo和重写父类People的两个方法:talk()和work();Teacher类除了从父类People继承的成员外还新增了一个属性:教师号tNo和重写父类People的两个方法:talk()和work()。如图2-7所示。

图2-7 人(People)、学生(Student)和教师(Teacher)类图

2.按照类图编制出类框架

                                                        // 人类(是学生类和教师类的父类)
        class People {
                String name;                   // 姓名
                int age;                       // 年龄
                public People(){                // 无参构造方法
                }
                public People(String name,int age){  // 带参构造方法
                }
                public void talk(){               // 说话行为
                }
                public void work(){              // 工作行为
                }
        }
                                                        // 学生类,派生自People类
        class Student extends People{
                String sNo;                    // 学号
                                                        // 构造方法
                public Student(String name, int age, String sNo) {
                }
                                                        // 以下重写继承自父类的方法
                public void talk(){               // 说话行为
                }
                public void work(){              // 工作行为
                }
        }
                                                        // 教师类,派生自People类
        class Teacher extends People {
                String tNo;                    // 教师号
                public Teacher(String name, int age, String tNo) {
                }
                                                        // 以下重写继承自父类的方法
                public void talk(){              // 说话行为
                }
                public void work(){              // 工作行为
                }
       }

3.实现类中的方法

                                                        // 实现People类中的方法
        public People(){                    // 无参构造方法
                name = "";
                age = 0;
        }
        public People(String name,int age){       // 带参构造方法
                this.name = name;
                this.age = age;
        }
        public void talk(){                   // 说话行为
                System.out.println("人会说话");
        }
        public void work(){                  // 工作行为
                System.out.println("人会工作");
        }
                                                        // 实现Student类中的构造方法
        public Student(String name, int age, String sNo) {
                super(name,age);               // 调用父类的带参构造方法
                this.sNo = sNo;
        }
        /***** 以下重写继承自父类的方法**********/
        public void talk(){                   // 说话行为
                System.out.println("学生正在回答老师的提问");
        }
        public void work(){                  // 工作行为
                System.out.println("学生的主要工作是学习");
        }
                                                        // 实现Teacher类中的构造方法
        public Teacher(String name, int age, String tNo) {
                super(name,age);               // 调用父类的带参构造方法
            this.tNo = tNo;
        }
        /***********以下重写继承自父类的方法*************/
        public void talk(){                   // 说话行为
            System.out.println("老师正在讲课");
        }
        public void work(){                  // 工作行为
            System.out.println("教师的主要工作是教书育人");
        }

4.定义主类

        public class Test {
            public static void main(String[] args) {
            }
        }

5.创建类的对象

        Student s=new Student("张三",18,"0900104");   // 创建学生类对象
        Teacher t=new Teacher("lee",20,"2009001");    // 创建教师类对象

6.访问对象

                                          // 打印学生对象的信息
      System.out.println("学生的姓名:" + s.name + "\t年龄:" + s.age + "\t学号:" + s.sNo);
      s.talk();
      s.work();
                                          // 打印教师对象的信息
      System.out.println("教师的姓名:" + t.name + "\t年龄:" + t.age + "\t教师号:" + t.tNo);
      t.talk();
      t.work();

7.代码调试并运行

(1)完整源代码如下:

        /**
         * 人类
         */
        class People {
            String name;                       // 姓名
            int age;                           // 年龄
            public People(){  // 无参构造方法
                name = "";
                age = 0;
            }
            public People(String name,int age){      // 带参构造方法
                this.name = name;
                this.age = age;
      }
      public void talk(){                   // 说话行为
          System.out.println("人会说话");
      }
      public void work(){                  // 工作行为
          System.out.println("人会工作");
      }
  }
  /**
  * 学生类,派生自People类
  */
  class Student extends People {
      String sNo;                        // 学号
                                      // 构造方法
      public Student(String name, int age, String sNo) {
          super(name,age);               // 调用父类的带参构造方法
          this.sNo = sNo;
      }
                                      // 以下重写继承自父类的方法
      public void talk() {
          System.out.println("学生正在回答老师的提问");
      }
      public void work(){                  // 工作行为
          System.out.println("学生的主要工作是学习");
      }
  }
  /**
  * 教师类,派生自People类
  */
  class Teacher extends People {
      String tNo;                        // 教师号
      public Teacher(String name, int age, String tNo) {
          super(name,age);               // 调用父类的带参构造方法
          this.tNo = tNo;
      }
                                      // 以下重写继承自父类的方法
      public void talk(){                   // 说话行为
          System.out.println("老师正在讲课");
      }
      public void work(){                  // 工作行为
          System.out.println("教师的主要工作是教书育人");
      }
  }
            public class Test {
            public static void main(String[] args) {
                Student s = new Student("张三", 18, "0900104");
                System.out.println("学生的姓名:" + s.name + "\t年龄:" + s.age + "\t学号:" + s.sNo);
                s.talk();
                s.work();
                Teacher t = new Teacher("lee", 20, "2009001");
                System.out.println("教师的姓名:" + t.name + "\t年龄:" + t.age + "\t教师号:" + t.tNo);
                t.talk();
                t.work();
            }
            }

(2)调试结果:

            学生的姓名:张三   年龄:18    学号:0900104
            学生正在回答老师的提问
            学生的主要工作是学习
            教师的姓名:lee     年龄:20教师号:2009001
            老师正在讲课
            教师的主要工作是教书育人