C++入门(9):类的继承(2)

来源:互联网 发布:怎样在农村淘宝开店 编辑:程序博客网 时间:2024/06/11 22:14

C++入门(9):类的继承(2)

构造器越简明越好,最好只用它来初始化各有关属性。
访问控制通过访问级别实现:
1)public : 任何代码都可以访问;
2)protected : 这个类本身和它的子类可以访问;
3)private : 只有这个类本身可以访问;

对函数/方法进行重载一定要慎重,重载方法/函数越多,程序就越不容易看懂;
覆盖方法
在对方法进行覆盖(注意不是重载)时一定要认真仔细;只要声明的输入参数和返回值与原来的不一致,则编写出来的方法就将是一个重载方法而不是一个覆盖方法。

友元关系
友元关系是类(函数)之间的一种特殊关系,这种关系允许友元访问对方的所有方法和属性;
声明一个友元关系:只要在类声明里的某个地方加上一条 friend class MyFriend; 语句就可以了;
我们应该只在没有其他办法时才使用友元关系,挑选友元的时候一定要谨慎。

下面通过举例详细讲解类继承中的问题:

#include <iostream>#include <string>class Pet{                                            //基类    public:        Pet(std::string theName) ;                    //构造函数        ~Pet() ;        void eat();        void sleep();        void play();                                  //覆盖方法    protected:        std::string name;    friend class PetRenamer;                          //声明友元关系};/*子类继承基类时,如果使用了protected保留字,则把基类的访问级别改为protected--如果它们原来是public的话,这将使得这个子类外部的代码无法通过这个子类去访问其基类中的public元素。如果使用了private保留字,则从基类继承来的每一个成员都当做它是用private保留字声明的情况来对待,即只有这个子类可以使用它从基类继承来的元素。*/class Dog : public Pet{                               //继承时使用public保留字,则继承的方法和属性的访问级别不发生任何改变    public:        Dog(std::string theName);        ~Dog();        void bark();        void play();};class Cat : public Pet{    public:        Cat(std::string theName) ;        ~Cat();        void climb();        void play();};class PetRenamer{                                     //与Pet类是友元关系的类    public:        PetRenamer(std::string theName);        void rename(Pet *pet, std::string newName);    private:        std::string name;};PetRenamer::PetRenamer(std::string theName){    name = theName;}void PetRenamer::rename(Pet *pet, std::string newName){    std::cout << this->name << " is going to rename " << pet->name << " to " << newName << std::endl;    pet->name = newName;}Pet::Pet(std::string theName)                         //定义构造器的时候,如果有默认参数,不用写出其初始化值 !!{    std::cout << "I am Pet's Constructor." << std::endl;    name = theName;    std::cout << name << std::endl;}Pet::~Pet(){    std::cout << "I am Pet's Destructor." << std::endl;}void Pet::eat(){    std::cout << "This " << name << " is eating... " << std::endl;}void Pet::sleep(){    std::cout << "This " << name << " is sleeping..." << std::endl;}void Pet::play(){    std::cout << "The pet is playing..." << std::endl;}Dog::Dog(std::string theName):Pet(theName)           //语法含义:当调用Dog()时(以theName作为输入参数),Pet()也将被调用(theName输入参数也会传递给它),赋值动作将实际发生在Pet()方法里{    std::cout << "I am Dog's Constructor." << std::endl;    std::cout << name << std::endl;}Dog::~Dog(){    std::cout << "I am Dog's Destructor." << std::endl;}void Dog::bark(){    std::cout << "This " << name << " is barking..." << std::endl;}void Dog::play()                                    //覆盖基类中的play()方法{    Pet::play();                                    //可以调用基类方法    std::cout << "The dog is playing" << std::endl;}Cat::Cat(std::string theName):Pet(theName){    std::cout << "I am Cat's Constructor." << std::endl;    std::cout << name << std::endl;}Cat::~Cat(){    std::cout << "I am Cat's Destructor." << std::endl;}void Cat::climb(){    std::cout << "This " << name << " is climbing..." << std::endl;}void Cat::play(){    Pet::play();                                      //调用基类方法    std::cout << "The cat is playing" << std::endl;}int main(int argc, char** argv) {    Pet pet("pet");    Dog dog("dog");                                   //先调用一次Pet的构造器,再调用一次Dog的构造器    Cat cat("cat");                                   //先调用一次Pet的构造器,再调用一次Cat的构造器    PetRenamer petRenamer("Jessica");    dog.eat();    dog.bark();    cat.climb();    pet.sleep() ;    pet.play();    dog.play() ;    cat.play();    std::cout << std::endl;    petRenamer.rename(&pet, "pet111") ;    pet.eat();    petRenamer.rename(&dog, "dog111") ;    dog.eat() ;    //程序结束时,依次调用类的析构器    return 0;}

运行结果为:

I am Pet's Constructor.petI am Pet's Constructor.dogI am Dog's Constructor.dogI am Pet's Constructor.catI am Cat's Constructor.catThis dog is eating...This dog is barking...This cat is climbing...This pet is sleeping...The pet is playing...The pet is playing...The dog is playingThe pet is playing...The cat is playingJessica is going to rename pet to pet111This pet111 is eating...Jessica is going to rename dog to dog111This dog111 is eating...I am Cat's Destructor.I am Pet's Destructor.I am Dog's Destructor.I am Pet's Destructor.I am Pet's Destructor.

C++入门(8):类的继承(1)

2 0
原创粉丝点击