继承(一)

来源:互联网 发布:多重网络怎么解决方法 编辑:程序博客网 时间:2024/05/14 23:17

继承的重要性我想只要是学习编程的人都知道吧 不管什么语言 只要它是面向对象的 我想 继承的概念都在其中

先说说继承的种类和方式

虽然这是一个看似很基础的问题 很久以前就学习了 也天天在使用 但最近看一些比较基础的书籍(大家都说基础最重要) 似乎也有了点新的理解 虽然以前也知道 但好像现在都忘得差不多了 因为在使用中 我们99%都是用的公有继承(public) 所以...

(一下很多都是自己总结的 难免出错 自己本来也是一个学生 和大家一起学习和复习吧)

c++中按照父类的多少 分为单继承 和 多继承(JAVA只支持单继承)

单继承自然不用多说 一个派生类 只有一个父类
但使用多继承就要考虑这样或者那样的问题 虽然也能带来众多好处 :代码上更好的复用
但需要考虑 1.类之间的关系到底是组合还是多重继承
             2.避免菱形继承
1.类之间的关系到底是组合还是多重继承
我在书上看到了这样一个例子来阐述 组合和多继承:
如果逻辑上A是B的一部分(a part of) 则不允许B从A中派生 而是要A和其他的东西组合成B

例如 眼Eye  鼻Nose  口Mouth 耳Ear 是头Head的一部分 所以类Head应该由它们组成 而不是派生而成 程序如下

class Eye
{
  public:
     void Look(void);
};

class Nose
{
  public:
     void Smell(void);
};

class Mouth
{
  public:
     void Eat(void);
};

class Ear
{
  public:
     void Listen(void);
};

class Head
{
  public:
    void Look(void){ m_eye.Look(); }
    void Smell(void){ m_nose.Smell(); }
    void Eat(void){ m_Mouth.Eat(); }
    void Listen(void){ m_Ear.Listen(); }

  private:
    Eye m_eye;
    Nose m_nose;
    Mouth m_mouth;
    Ear m_ear;
};


下面这样做是不对的
class Head: public Eye,public Nose,public Mouth,public Ear
{
};

2.菱形继承
见下面的虚继承

继承更具其不同的方式可以分为 公有继承 保护继承 和 私有继承
1.公有继承
从父类继承来的属性和方法的访问方式不会改变(即基类的公有成员还是派生类的公有成员 基类的保护成员还是派生类的保护成员)
如 class A{...};
class B:public A{...};
则B类可以访问A类的公有成员和保护成员 不能直接访问A类的私有成员和保护成员

2.私有继承
从基类中继承来的公有成员和保护成员都将变为派生类的私有成员 而基类的保护成员变得不可见
如 class A{
    public:
            int a;
 };

 class B: private A{
    public:
       int GetA(void){
           return a;
          }

 };

调用 B b;
     b.a;//错误
     b.GetA();//正确


3.保护继承
基类成员对派生类的可见性对派生类来说,公有成员和保护成员时可见的。基类的公有成员和保护成员都变成了派生类的保护成员 并且不能被派生类的子类所访问。基类的私有成员对派生类是不可见的

在实际运用中 其实我们使用(可能是自己没常从事正规的开发 只是一些学习) 绝大多数是共有继承 在一本书上看到过这样一句话:保护继承和私有继承只是在技术上讨论时有一席之地.

 

下面说说虚继承
以前没常注意这个概念 但最近常遇到 涉及到sizeof计算大小时 还有就是所谓的菱形继承了
形如下

class A{...};
class B:public A{...};
class C:public A{...};
class D:public B,public D{...};
咋一看或许没什么问题 但仔细想想继承的逻辑结构 D继承自B,C 而B,C都继承自A 似乎D中出现了2次A 利用虚继承可以解决这个问题
形如下

class A{...};
class B:public virtual A{...};
class C:public virtual A{...};
class D:public B,public D{...};
这样 A就成了虚拟基类 只在D中出现一次 节省了空间
将共同基类设置为虚基类,这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射。这样就解决了同名成员的惟一标识问题。C++中的流操作就是利用虚继承解决了上述问题

接触virtual多了 似乎已碰到它都会涉及到多态和动态绑定(运行时绑定/晚绑定)

 

 

 

 

 

 

 

原创粉丝点击