c++的继承方式和派生对象的初始化

因为访问控制的权限有3中,public,protected,private,它们分别是不同的访问等级,
同理类的继承也有这3种方式

公有(public)继承,基类成员保持自己原有的访问方式不变,public 还是public ,protected还是protected,private还是private。
保护(protected)继承,基类的public成员和protected成员在派生类中都为protected,private还是private。
私有(private)继承,基类的所有成员在派生类中都为private成员。
继承时注意的事项
1区分好类的内部访问权限和外部访问权限
一个类所有的数据函数于成员函数对类的内部成员可见(开放),访问权限控制数据成员和成员函数是否提供类外访问

#include <iostream>
using namespace std;
class Base{
    
    private:
    int a,b;       //定义基类,设置两个整形的成员变量,把访问权限设置为private
    
    public:
    Base(){
        a= 1,b=2;
    }
    void showab(){
        cout<<a<<b<<endl;
    }
    
};
class B1:public Base{
    private:
    char i,j;
    
    public:
    B1(){
        i = '2',j = '3';
        
    }
    void showabij(){
        cout<<a<<b<<i<<j;   //在子类的方法中去访问基类的private成员变量a,b;
    }                        //编译时报错,提示a,b,是私有的,无法被我们的子类方法去访问
    
};
int main(){
    B1 o;
    o.showabij();
}


这就是访问控制的效果,为了实现输出a,b我们可以稍加修改

void showabij(){
        Base::showab();  //调用基类的方法
        cout<<i<<j;
    }



2.派生类进一步限制了对所继承基类的基类成员的访问
如果继承方式是private的,则不论基类中的成员是公有的还是保护的权限,被派生类继承后就全是私有的不再提供任何的类外访问,下面举个例子

#include <iostream>
#include <string>
using namespace std;
class Base {
 public:
    string name = "默认为张三";
    int age = 0;
    char sex = 'm';
    Base() {};

    Base(int age, string name, char sex) {
        this->name = name;
        this->age = age;
        this->sex = sex;
    }
    string getName() {
        return name;
    }
    void showName() {
        cout << name;
    }
    void showMESS() {
        cout << name << age << sex;
    }

};
class B1 :private Base {     //在B1的private继承后,所有继承的属性变成私有的

private:
    int num = 0;
    double bod_length = 0;
public:
    B1() {};
    B1(int n, double b){
        num = n; bod_length = b;
    }

    void showMESSAGE() {
        cout << num<< bod_length;
        cout << age << name << sex;
    
    }

};
class B2 :private B1 {       //用B2来继承B1看一下效果
private:
    double weighet;
public:
    B2(double weighet) { this->weighet = weighet; };
    void show_MESS() {
        cout << weighet;
        cout << num << bod_length;     //程序报错,提示无法访问num,等变量
        cout << age << name << sex;
    }

};

int main() {
    B1 bn =  B1(123, 18.7);  //调用构造函数初始化
    B2 bn1 = B2(99.45);
    bn1.show_MESS();   //无法访问private的成员变量
    int i; cin >> i;
}


如果要运行的话,把B1,B2的继承方式改为protected或public即可

在这里插入图片描述
3基类保护(protected)成员是实现继承下信息隐藏的最好方法
利用protected的方式继承能够让类的成员在本类和子类之间相互可见能够在继承中共享(除了private成员)

#include <iostream>   //将继承方式改为protected后
#include <string>
using namespace std;
class Base {
 public:
    string name = "Oh year sir♂";
    int age = 0;
    char sex = 'm';
    Base() {};

    Base(int age, string name, char sex) {
        this->name = name;
        this->age = age;
        this->sex = sex;
    }
    string getName() {
        return name;
    }
    void showName() {
        cout << name;
    }
    void showMESS() {
        cout << name << age << sex;
    }

};
class B1 :protected Base {

protected:
    int num = 0;
    double bod_length = 0;
public:
    B1() {};
    B1(int n, double b){
        num = n; bod_length = b;
    }

    void showMESSAGE() {
        cout << num<< bod_length;
        cout << age << name << sex;
    
    }

};
class B2 :protected B1 {
private:
    double weighet;
public:
    B2(double weighet) { this->weighet = weighet; };
    void show_MESS() {
        cout << weighet;
        cout << num << bod_length;
        cout << age << name << sex;
    }
};
int main() {
    B1 bn =  B1(123, 18.7);
    bn.showMESSAGE();
    B2 bn1 = B2(99.45);
    int i; cin >> i;
}


派生类对象的初始化
定义了一个派生类之后,它将继承基类中除了构造函数和析构函数的全部成员
因此当生成派生类的一个对象时,该对象包含全部的数据成员。
派生类的初始化是通过调用派生类的构造函数来实现的
格式1:构造函数名(参数表):基类构造函数名(参数表);
格式2:构造函数名(参数表):基类构造函数名(参数表),对象成员名(参数表);
下面给出例子

#include <iostream>
#include <string>
using namespace std;
class Car {                  //抽象类
public:
    string carname;           //车名

    string product_place;

    unsigned  hour_speed;

    unsigned  roll;

    unsigned   price;

    unsigned   addspeed0_100;


    Car(string carname, string product_place, unsigned hour_speed, unsigned roll, unsigned price, unsigned addspeed0_100) {
        this->carname = carname;
        this->product_place = product_place;
        this->hour_speed = hour_speed;
        this->roll = roll;
        this->price = price;
        this->addspeed0_100 = addspeed0_100;

        cout << "进入构造方法" << endl;
    };
    Car(string carname) {        //重载构造方法
        this->carname = carname;
    }
    ~Car();
public:
    virtual void run() {

    }   //虚方法
};
Car::~Car() {
    cout << "进入析构器" << endl;
}
class Ferrari :public Car {     //定义车的子类,法拉利继承父类车

public:
    Ferrari() :Car("Ferrari") {     //派生类的构造函数
        cout << "hhh" << endl;
    }
    void run() {
        cout << "从写父类的方法" << endl;
        cout << "法拉利正在跑.............唰!!!" << endl;
    }

};
class toyotA : public Car {  //定义TOYOTA,继承父类

public:

    toyotA(string carname, string product_place, unsigned hour_speed, unsigned roll, unsigned price, unsigned addspeed0_100) :Car(carname, product_place, hour_speed, roll, price, addspeed0_100) {
        cout << "我重载了父类的构造方法" << endl;   //定义派生类的构造函数
    }
    void run() {
        cout << "重写父类方法" << endl;
        cout << "我是一辆小丰田" << endl;

    }
    void downfromMontains() {
        cout << carname << endl;
        cout << "注意AE86下山了!!!" << endl;

    }

};
int main() {
    Ferrari p458;
    toyotA AE86 = toyotA("AE86", "Japen", 150, 4, 200000, 9);
    AE86.downfromMontains();
    char i;
    cin >> i;
}


在这里插入图片描述
现在要到12点了先溜为敬,告辞。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值