C++继承的问题 10

看到一句C++中继承关系是概念上的父子关系,不是个体的父子关系。怎么理解这个”概念上的“和”个体的“?... 看到一句C++中继承关系是概念上的父子关系,不是个体的父子关系。怎么理解这个”概念上的“和”个体的“? 展开
 我来答
长沙汇德教育咨询有限公司
2016-06-22
长沙汇德教育咨询有限公司
汇德教育,专注于职(执)业资格培训、学历教育、证书挂靠、人才服务、教育产品研发为一体的大型职业教育机构。汇德教育拥有超前的发展理念,领先的发展战略,良好的发展基础,为企业和个人提供全方位服务
向TA提问
展开全部
在C++中继承主要有三种关系:public、protected和private。这三种继承关系中public
继承是最为常用的一种继承关系,代表了接口继承含义,而他们分别具体代表的含义如下:
1. public
从语义角度上来说,public继承是一种接口继承,根据面向对象中的关系而言就是,子类
可以代替父类完成父类接口所声明的行为,也就是必须符合“Liskov替换原则(LSP)”,
此时子类可以自动转换成为父类的接口,完成接口转换。
从语法角度上来说,public继承会保留父类中成员(包括函数和变量等)的可见性不变,
也就是说,如果父类中的某个函数是public的,那么在被子类继承后仍然是public的。

2. protected
从语义角度上来说,protected继承是一种实现继承,根据面向对象中的关系而言就是,
子类不能代替父类完成父类接口所声明的行为,也就是不符合“Liskov替换原则(LSP)”,
此时子类不能自动转换成为父类的接口,就算通过类型转换(static_cast和dynamic_cast)
也会得到一个空指针。
从语法角度上来说,protected继承会将父类中的public可见性的成员修改成为protected
可见性,相当于在子类中引入了protected成员,这样一来在子类中同样还是可以调用父
类的protected和public成员,子类的子类就也可以调用被protected继承的父类的protected
和public成员。
例如:
class CSample1 {
protected:
void printProtected() {}
public:
void printPublic() {}
};
class CSample2 : protected CSample1 {

};
class CSample3 : public CSample2 {
void print3() {
printProtected();
printPublic();
}
};
3. private
从语义角度上来说,private继承是一种实现继承,根据面向对象中的关系而言就是,
子类不能代替父类完成父类接口所声明的行为,也就是不符合“Liskov替换原则(LSP)”,
此时子类不能自动转换成为父类的接口,就算通过类型转换(static_cast和dynamic_cast)
也会得到一个空指针。
从语法角度上来说,private继承会将父类中的public和protected可见性的成员修改成为
private可见性,这样一来虽然子类中同样还是可以调用父类的protected和public成员,
但是在子类的子类就不可以再调用被private继承的父类的成员了。
class CSample1 {
protected:
void printProtected() {}
public:
void printPublic() {}
};
class CSample2 : private CSample1 {

};
class CSample3 : public CSample2 {
void print3() {
printProtected(); // 编译错误,不可以调用该函数
printPublic(); // 编译错误,不可以调用该函数
}
};

在面向对象的理论中有两种概念:接口、实现,所以就出现了所谓的接口继承和实现继
承两种关系。而protected和private就是实现继承中所要用到的,其实protected和private
两者则约束继承时并没有形成两种不同的继承类别,而仅仅只是为了方便C++类方法的传递
调用而设计的,其实在java这样面向对象要求更为严格的语言当中,没有实现继承,他必须
通过委托方式来完成这一概念,如果熟悉java就会明白,如果一个对象要使用另外一个对象
的接口功能,而自身又不能够充当该对象所扮演的角色时,就会通过委托来完成,这样一来
就必须在对象中包含一个委托对象,通过对象调用语法来完成功能;在C++中就可以通过
protected和private继承来完成java中的委托关系(当然C++也可以形成对象委托关系),
那么这种情况下protected继承就容许委托可以传递(也就是被多级子类调用),而private
继承是不容许委托被传递的。
eykabin
2016-04-20 · 知道合伙人教育行家
eykabin
知道合伙人教育行家
采纳数:7039 获赞数:40220
本人毕业于河南省职业中等专业学校,从业五年来一直从事煤矿机电技术工作。

向TA提问 私信TA
展开全部
给你举个例子吧:
class B{
protected:
string strWebSite;
public:
string& getWebSite(){return strWebSite;}
void setWebSite(string& strValue){strWebSite = strValue;}
};
class D: public B{
public:
string& getValue(){ return strWebSite;}
void setValue(string& strValue){ strWebSite = strValue;}
}
B是父类,拥有一个protected成员strWebSite;D是子类没有定义新的数据成员。如果我们定义一个D对象
D d;
B& rb = d;
D& rd = d;

rb.setWebSite("b string");
cout << rb.getWebSite();
cout << rd.getValue();
二者输出相同,也就是“在父类中修改该成员变量以后,子类继承的该成员变量的值发生相应变化”

rd.setValue("d string");
cout << rb.getWebSite();
cout << rd.getValue();
二者输出也相同,也就是你说的“反之也成立得情况”

这个保护类型的成员其实只是d对象中的一块内存,所以通过父类或子类引用访问的结果是一样的。

但是如果分别使用B和D两个类定义两个实例如:
B b1;
D d1;
则,b1和d1没有任何关系。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
存集城187
2016-04-04 · TA获得超过1220个赞
知道小有建树答主
回答量:1136
采纳率:0%
帮助的人:204万
展开全部
  1. 首先你一定要理解三种继承的区别,另外要清楚这里说的转换是 指针类型 的转换。
    这个问题要解释清楚比较复杂,我简单逐句使用实例给你演示说明一下。
         类A{...};作为基类
    1、 公有继承派生类B:public A{...}现在B具有A中public和protect属性了,定义A a 和B b,
            public 继承,则用户代码和后代类都可以使用派生类到基类的转换:
           A* c = &b 这是允许的,因为B是公有继承的A;但反之就不允许了,相信这个你是理解的
    2、private 或 protected 继承派生的,则用户代码不能将派生类型对象转换为基类对象。
        这句话也很容易理解,因为保护继承的话B:protect A{...},A中public元素在B中是protect的。
        而类似的私有继承的所有元素都是私有的,当然不允许指针转换了;

    “如果是 private 继承,则从 private 继承类派生的类不能转换为基类。如果是 protected 继承,则后续派生类的成员可以转换为基类类型。”这两句要注意是指的继承类再次派生的子类,如下:
    A{...}
    B:protect A{}
    C:public B{}这样继承B就作为C的基类了,C类中拥有A类中的所有属性,只不过A中public成员变成了protect成员了,但是作为子类仍然可以操作这个成员;

    D:private A{}
    E:public D{}这样继承E中其实是继承不到任何属于A中的元素的了,连访问成员都做不到更谈不到转换了

    实际上就我个人感觉来说,问题中的用语是很不清晰的,因为毕竟是翻译过来的,我们学习的时候也没有必要总抱着一本书来学习,多读一些互相对照才能更准确的理解

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式