C++快速入门 第十九讲:覆盖方法和重载方法

发布时间 2023-08-18 14:56:58作者: 一杯清酒邀明月

覆盖是指派生类函数覆盖基类函数(函数名字参数相同且基类函数必须有virtual关键字)

以上学习可知可以通过创建新的子类来重用现有的代码(继承)

当我们需要在基类里提供一个通用的函数,但在它的某个子类里需要修改这个方法的实现,覆盖(overriding)就可以做到。

实例1:覆盖应用

  1 //级别            允许谁来访问
  2 //public           任何代码 
  3 //protected        这个类本身和它的子类 
  4 //private          只有这个类本身
  5 #include <iostream>
  6 #include <string>
  7 
  8 class Animal//定义Animal类
  9 {
 10 public:
 11     std::string mouth;
 12     //std::string name;
 13     
 14     Animal(std::string theName);//类Animal的构造器 
 15     void eat();
 16     void sleep();
 17     void drool();//流鼻涕
 18 protected:
 19     std::string name;
 20 };
 21 Animal::Animal(std::string theName)//类Animal构造器函数 
 22 {
 23     name = theName;
 24 }
 25 
 26 class Pig:public Animal//类Pig继承于类Animal
 27 {
 28 public:
 29     Pig(std::string theName);//类Pig的构造器
 30     void climb();
 31     void eat();   //new  再一次声明,以便原函数可以覆盖修改 
 32 };
 33 Pig::Pig(std::string theName):Animal(theName)//类Pig的构造函数继承于类Animal的构造函数 
 34 {
 35     
 36 } 
 37 
 38 class Turtle:public Animal//类Turtle继承于类Animal
 39 {
 40 public:
 41     Turtle(std::string theName);//类Pig的构造器
 42     void swim();
 43     void eat();   //new  再一次声明,以便原函数可以覆盖修改 
 44 };
 45 Turtle::Turtle(std::string theName):Animal(theName)//类Turtle的构造函数继承于类Animal的构造函数参数 
 46 {
 47     
 48 }
 49 
 50 void Animal::eat()//Animal类中的方法函数
 51 {
 52     std::cout << "I'm eatting!" << std::endl;
 53 }
 54 void Animal::sleep()
 55 {
 56     std::cout << "I'm sleeping!Don't disturb me!" << std::endl;
 57 }
 58 void Animal::drool()
 59 {
 60     std::cout << "我是公的,看到母的会流口水 流口水。。。" << std::endl;
 61 }
 62 
 63 void Pig::climb()//类Pig中的climb方法函数
 64 {
 65     std::cout << "我是一只漂亮的小母猪猪,我会上树,邱。。。" << std::endl;
 66 }
 67 void Turtle::swim()//类Turtle中的swim方法函数
 68 {
 69     std::cout << "我是一只小甲鱼,当母猪抓我,我就游到海里,哈。。。" << std::endl;
 70 }
 71 void Pig::eat()//重新声明eat方法 
 72 {
 73     Animal::eat();//可省去 
 74     std::cout << "我在吃鱼\n\n" << std::endl;
 75 }
 76 void Turtle::eat()//重新声明eat方法 
 77 {
 78     Animal::eat();//可省去
 79     std::cout << "我正在吃东坡肉!\n\n" << std::endl;
 80 }
 81 
 82 
 83 int main()
 84 {
 85     Pig pig("小猪猪");//定义一个对象pig,由于其继承于类Animal,
 86     //且构造函数也继承于类Animal的构造函数,所以参数"小猪猪"将赋值给类pig中的名字属性name 
 87     Turtle turtle("小甲鱼");//定义一个对象turtle
 88     
 89     //pig.name = "小甲鱼"; //由于name被保护起来,所以赋值将报错 
 90     
 91 //  std::cout << "这只猪的名字是:" << pig.name << std::endl;        
 92 //    std::cout << "每只乌龟都有个伟大的名字:" << turtle.name << std::endl; 
 93 
 94     pig.eat();
 95     turtle.eat();
 96     pig.climb();
 97     turtle.swim();
 98 
 99     return 0;
100 }

重载机制使你可以定义多个同名的方法(函数),只是它们的输入参数必须不同。(因为编译器是依靠不同的输入参数来区分不同的方法)

实例2:重载应用

 1 //级别            允许谁来访问
 2 //public           任何代码 
 3 //protected        这个类本身和它的子类 
 4 //private          只有这个类本身
 5 #include <iostream>
 6 #include <string>
 7 
 8 class Animal//定义Animal类
 9 {
10 public:
11     std::string mouth;
12     //std::string name;
13     
14     Animal(std::string theName);//类Animal的构造器 
15     void eat();
16     void eat(int eatCount); 
17     void sleep();
18     void drool();//流鼻涕
19 protected:
20     std::string name;
21 };
22 Animal::Animal(std::string theName)//类Animal构造器函数 
23 {
24     name = theName;
25 }
26 
27 class Pig:public Animal//类Pig继承于类Animal
28 {
29 public:
30     Pig(std::string theName);//类Pig的构造器
31     void climb();
32 };
33 Pig::Pig(std::string theName):Animal(theName)//类Pig的构造函数继承于类Animal的构造函数 
34 {
35     
36 } 
37 
38 class Turtle:public Animal//类Turtle继承于类Animal
39 {
40 public:
41     Turtle(std::string theName);//类Pig的构造器
42     void swim();
43 };
44 Turtle::Turtle(std::string theName):Animal(theName)//类Turtle的构造函数继承于类Animal的构造函数参数 
45 {
46     
47 }
48 
49 void Animal::eat()//Animal类中的方法函数
50 {
51     std::cout << "I'm eatting!" << std::endl;
52 }
53 void Animal::eat(int eatCount)
54 {
55     std::cout << "我吃了" << eatCount << "碗馄饨!\n";
56 }
57 void Animal::sleep()
58 {
59     std::cout << "I'm sleeping!Don't disturb me!" << std::endl;
60 }
61 void Animal::drool()
62 {
63     std::cout << "我是公的,看到母的会流口水 流口水。。。" << std::endl;
64 }
65 
66 void Pig::climb()//类Pig中的climb方法函数
67 {
68     std::cout << "我是一只漂亮的小母猪猪,我会上树,邱。。。" << std::endl;
69 }
70 void Turtle::swim()//类Turtle中的swim方法函数
71 {
72     std::cout << "我是一只小甲鱼,当母猪抓我,我就游到海里,哈。。。" << std::endl;
73 }
74 
75 int main()
76 {
77     Pig pig("小猪猪");//定义一个对象pig,由于其继承于类Animal,
78     //且构造函数也继承于类Animal的构造函数,所以参数"小猪猪"将赋值给类pig中的名字属性name 
79     Turtle turtle("小甲鱼");//定义一个对象turtle
80     
81     //pig.name = "小甲鱼"; //由于name被保护起来,所以赋值将报错 
82 //  std::cout << "这只猪的名字是:" << pig.name << std::endl;        
83 //    std::cout << "每只乌龟都有个伟大的名字:" << turtle.name << std::endl; 
84 
85     pig.eat();
86     turtle.eat();
87     
88     pig.eat(15);
89     pig.climb();
90     turtle.swim();
91 
92     return 0;
93 }

在对方法进行覆盖(注意区分覆盖和重载)时,一定要看仔细,因为只要声明的输入参数和返回值与原来的不一致,你编写出来的就将是一个重载的方法而不是覆盖方法。

实例3:子类内声明重载

 1 //级别            允许谁来访问
 2 //public           任何代码 
 3 //protected        这个类本身和它的子类 
 4 //private          只有这个类本身
 5 #include <iostream>
 6 #include <string>
 7 
 8 class Animal//定义Animal类,基类 
 9 {
10 public:
11     std::string mouth;
12     //std::string name;
13     
14     Animal(std::string theName);//类Animal的构造器 
15     void eat();
16     
17     void sleep();
18     void drool();//流鼻涕
19 protected:
20     std::string name;
21 };
22 Animal::Animal(std::string theName)//类Animal构造器函数 
23 {
24     name = theName;
25 }
26 
27 class Pig:public Animal//类Pig继承于类Animal,子类 
28 {
29 public:
30     Pig(std::string theName);//类Pig的构造器
31     void climb();
32     void eat(int eatCount);//重载 
33 };
34 Pig::Pig(std::string theName):Animal(theName)//类Pig的构造函数继承于类Animal的构造函数 
35 {
36     
37 } 
38 
39 class Turtle:public Animal//类Turtle继承于类Animal
40 {
41 public:
42     Turtle(std::string theName);//类Pig的构造器
43     void swim();
44 };
45 Turtle::Turtle(std::string theName):Animal(theName)//类Turtle的构造函数继承于类Animal的构造函数参数 
46 {
47     
48 }
49 
50 void Animal::eat()//Animal类中的方法函数
51 {
52     std::cout << "I'm eatting!" << std::endl;
53 }
54 
55 void Animal::sleep()
56 {
57     std::cout << "I'm sleeping!Don't disturb me!" << std::endl;
58 }
59 void Animal::drool()
60 {
61     std::cout << "我是公的,看到母的会流口水 流口水。。。" << std::endl;
62 }
63 
64 void Pig::climb()//类Pig中的climb方法函数
65 {
66     std::cout << "我是一只漂亮的小母猪猪,我会上树,邱。。。" << std::endl;
67 }
68 void Pig::eat(int eatCount)
69 {
70     std::cout << "我吃了" << eatCount << "碗馄饨!\n";
71 }
72 
73 void Turtle::swim()//类Turtle中的swim方法函数
74 {
75     std::cout << "我是一只小甲鱼,当母猪抓我,我就游到海里,哈。。。" << std::endl;
76 }
77 
78 int main()
79 {
80     Pig pig("小猪猪");//定义一个对象pig,由于其继承于类Animal,
81     //且构造函数也继承于类Animal的构造函数,所以参数"小猪猪"将赋值给类pig中的名字属性name 
82     Turtle turtle("小甲鱼");//定义一个对象turtle
83     
84     //pig.name = "小甲鱼"; //由于name被保护起来,所以赋值将报错 
85 //  std::cout << "这只猪的名字是:" << pig.name << std::endl;        
86 //    std::cout << "每只乌龟都有个伟大的名字:" << turtle.name << std::endl; 
87 
88     //pig.eat();   由于eat在子类中被重载,所以不能再被调用;如果在基类重载则可以调用 
89     turtle.eat();
90     
91     pig.eat(15);//重载函数 
92     pig.climb();
93     turtle.swim();
94 
95     return 0;
96 }