继承概念,继承访问级别,继承方式

目录

1、继承的概念与意义

2、继承中的访问级别

1、问题

2、继承中的访问级别

3、组合与继承的综合实例

3、不同的继承方式

4、小结


1、继承的概念与意义

类之间的关联关系

      -组合关系:整体与部分的关系;

      -继承关系:父子关系

组合关系的特点 

      -将其它类的对象作为当前类的成员使用 

      -当前类的对象与成员对象的生命期相同 

      -成员对象在用法上与普通对象完全一致

继承指类之间的父子关系 

      -子类拥有父类的所有属性和行为 

      -子类就是—种特殊的父类(独立存在) 

      -子类对象可以当作父类对象使用 

      -子类中可以添加父类没有的方法和属性

继承的实例分析

继承初体验 test.cpp

#include <iostream>  
  
using namespace std;  
  
// 父类(基类)
class Parent  
{  
    int mv;  
public:  
    Parent()  
    {  
        cout << "Parent()" << endl;  
        mv = 100;  
    }  
    void method()  
    {  
        cout << "mv = " << mv << endl;  
    }  
};  

// 子类(派生类),拥有父类所有的属性和方法  
class Child : public Parent
{  
public:  

    // 子类可以添加父类没有的属性和方法
    void hello()  
    {  
        cout << "I'm Child class!" << endl;  
    }  
};  
  
int main()  
{     
    Child c;  
      
    c.hello();  
    c.method();  // 子类对象可以当父类对象使用,子类拥有父类的属性和方法  --> c.Parent::method();
      
    return 0;  
}  

 

重要规则: 

      -子类就是一个特殊的父类 

      -子类对象可以直接初始化父类对象 

      -子类对象可以直接赋值给父类对象

继承的意义

继承是C++中代码复用的重要手段。通过继承,可以获得父类的所有功能,

并且可以在子类中重写已有功能,或者添加新功能。 

编程实验

继承的强化练习   test.cpp

#include <iostream>  

using namespace std;  
  
class Memory  
{  
public:  
    Memory()  
    {  
        cout << "Memory()" << endl;  
    }  
    ~Memory()  
    {  
        cout << "~Memory()" << endl;  
    }  
};  
  
class Disk  
{  
public:  
    Disk()  
    {  
        cout << "Disk()" << endl;  
    }  
    ~Disk()  
    {  
        cout << "~Disk()" << endl;  
    }     
};  
  
class CPU  
{  
public:  
    CPU()  
    {  
        cout << "CPU()" << endl;  
    }  
    ~CPU()  
    {  
        cout << "~CPU()" << endl;  
    }      
};  
  
class MainBoard  
{  
public:  
    MainBoard()  
    {  
        cout << "MainBoard()" << endl;  
    }  
    ~MainBoard()  
    {  
        cout << "~MainBoard()" << endl;  
    }      
};  
  
class Computer  
{  
    Memory mMem;  // 父类组合其他类
    Disk mDisk;  
    CPU mCPU;  
    MainBoard mMainBoard;  
public:  
    Computer()  
    {  
        cout << "Computer()" << endl;  
    }  
    void power()  
    {  
        cout << "power()" << endl;  
    }  
    void reset()  
    {  
        cout << "reset()" << endl;  
    }  
    ~Computer()  
    {  
        cout << "~Computer()" << endl;  
    }  
};  
  
class HPBook : public Computer  
{  
    string mOS;  
public:  
    HPBook()  
    {  
        mOS = "Windows 8";  
    }  
    void install(string os)  
    {  
        mOS = os;  
    }  
    void OS()  
    {  
        cout << mOS << endl;  
    }  
};  
  
class MacBook : public Computer  
{  
public:  
    void OS()  
    {  
        cout << "Mac OS" << endl;  
    }  
};  
  
int main()  
{     
    HPBook hp;  
      
    hp.power();  
    hp.install("Ubuntu 16.04 LTS");  
    hp.OS();  
      
    cout << endl;  
      
    MacBook mac;  
      
    mac.OS();  
      
    return 0;  
}  

 

 

2、继承中的访问级别

1、问题

问题:子类是否可以直接访问父类的私有成员?、

根据面向对象理论:

根据C++语法:

 

编程实验

继承中的访问级别  test.cpp

//error.cpp
#include <iostream>  
  
using namespace std;  
  
class Parent  
{  
private:  
    int mv;  
public:  
    Parent()  
    {  
        mv = 100;  
    }  
      
    int value()  
    {  
        return mv;  
    }  
};  
  
class Child : public Parent  
{  
public:  
    int addValue(int v)  
    {  
        mv = mv + v;    // error 如何访问父类的非公有成员?  
    }  
};  
  
int main()  
{     
    return 0;  
}  

2、继承中的访问级别

面向对象中的访问级别包括:publicprivateprotected

关键字protected的意义 

      -修饰的成员不能被外界直接访问 

      -修饰的成员可以被子类直接访问 

编程实验

protected初体验     test.cpp

#include <iostream>  

using namespace std;  
  
class Parent  
{  
protected:  
    int mv;  
public:  
    Parent()  
    {  
        mv = 100;  
    }  
      
    int value()  
    {  
        return mv;  
    }  
};  
  
class Child : public Parent  
{  
public:  
    int addValue(int v)  
    {  
        mv = mv + v;   // 可以直接访问父类的protected成员变量   
    }  
};  
  
int main()  
{     
    Parent p;  
      
    cout << "p.mv = " << p.value() << endl;  
      
    // p.mv = 1000;    // error  不能被外界直接访问
      
    Child c;  
      
    cout << "c.mv = " << c.value() << endl;  
      
    c.addValue(50);  
      
    cout << "c.mv = " << c.value() << endl;  
      
    // c.mv = 10000;  // error  
      
    return 0;  
}  

 

定义类时访问级别的选择

    

3、组合与继承的综合实例

 

 Point,Line与Object是继承关系,Point和Line是组合关系

编程实验

综合实例    test.cpp

#include <iostream>  
#include <string>  
#include <sstream>  
  
using namespace std;  
  
class Object  
{  
protected:  
    string mName; 
    string mInfo;  
public:  
    Object()  
    {  
        mName = "Object";  
        mInfo = "";  
    }  
    string name()  
    {  
        return mName;  
    }  
    string info()  
    {  
        return mInfo;  
    }  
};  
  
class Point : public Object  
{  
private:  
    int mX;  
    int mY;  
public:  
    Point(int x = 0, int y = 0)  
    {  
        ostringstream s;  
          
        mX = x;  
        mY = y;  
        mName = "Point";  
          
        s << "P(" << mX << ", " << mY << ")";  
          
        mInfo = s.str();  
    }  
    int x()  
    {  
        return mX;  
    }  
    int y()  
    {  
        return mY;  
    }  
};  
  
class Line : public Object  
{  
private:  
    Point mP1;  
    Point mP2;  
public:  
    Line(Point p1, Point p2)  
    {  
        ostringstream s;  
          
        mP1 = p1;  
        mP2 = p2;  
        mName = "Line";  
          
        s << "Line from " << mP1.info() << " to " << mP2.info();  
          
        mInfo = s.str();  
    }  
    Point begin()  
    {  
        return mP1;  
    }  
    Point end()  
    {  
        return mP2;  
    }  
};  
  
int main()  
{     
    Object o;  
    Point p(1, 2);  
    Point pn(5, 6);  
    Line l(p, pn);  
      
    cout << o.name() << endl;  
    cout << o.info() << endl;  
      
    cout << endl;  
      
    cout << p.name() << endl;  
    cout << p.info() << endl;  
      
    cout << endl;  
      
    cout << l.name() << endl;  
    cout << l.info() << endl;  
      
    return 0;  
}  

  

 

3、不同的继承方式

C++中支持三种不同的继承方式 

      -public继承 :父类成员在子类中保持原有访问级别 

      -private继承 :父类成员在子类中变为私有成员

      -protected继承 :父类中的公有成员变为保护成员,其它成员保持不变

                        继承成员的访问属性 = Max 继承方式父类成员的访问属性 }

                                         C++中的默认继承方式为 private

 

编程实验

继承与访问级别深度实践   test.cpp

#include <iostream>  
#include <string>  
  
using namespace std;  
  
class Parent  
{  
protected:  
    int m_a;  
protected:  
    int m_b;  
public:  
    int m_c;  
      
    void set(int a, int b, int c)  
    {  
        m_a = a;  
        m_b = b;  
        m_c = c;  
    }  
};  
  
class Child_A : public Parent  
{  
public:  
    void print()  
    {  
        cout << "m_a" << m_a << endl;  
        cout << "m_b" << m_b << endl;  
        cout << "m_c" << m_c << endl;  
    }  
};  
  
class Child_B : protected Parent  
{  
public:  
    void print()  
    {  
        cout << "m_a" << m_a << endl;  
        cout << "m_b" << m_b << endl;  
        cout << "m_c" << m_c << endl;  
    }  
};  
  
class Child_C : private Parent  
{  
public:  
    void print()  
    {  
        cout << "m_a" << m_a << endl;  
        cout << "m_b" << m_b << endl;  
        cout << "m_c" << m_c << endl;  
    }  
};  
  
int main()  
{     
    Child_A a;  
    Child_B b;  
    Child_C c;  
      
    a.m_c = 100;  
    // b.m_c = 100;    // Child_B 保护继承自 Parent, 所以所有的 public 成员全部变成了 protected 成员, 因此外界无法访问  
    // c.m_c = 100;    // Child_C 私有继承自 Parent, 所以所有的成员全部变成了 private 成员, 因此外界无法访问  
      
    a.set(1, 1, 1);  
    // b.set(2, 2, 2);  
    // c.set(3, 3, 3);  
      
    a.print();  
    b.print();  
    c.print();  
      
    return 0;  
}  

遗憾的事实

            一般而言,C++工程项目中只使用public继承 

            C++的派生语言多只支持—种继承方式( public继承 ) 

            protected和private继承带来的复杂性远大于实用性 

编程实验

C++派生语言初探     test1.d     test2.cs     testt3.java

test1.d

module D_Demo;  
  
import std.stdio;  
import std.string;  
  
class Obj  
{  
protected:  
    string mName;  
    string mInfo;  
public:  
    this()  
    {  
        mName = "Object";  
        mInfo = "";  
    }  
    string name()  
    {  
        return mName;  
    }  
    string info()  
    {  
        return mInfo;  
    }  
}  
  
class Point : Obj  
{  
private:  
    int mX;  
    int mY;  
public:  
    this(int x, int y)  
    {  
        mX = x;  
        mY = y;  
        mName = "Point";  
        mInfo = format("P(%d, %d)", mX, mY);  
    }  
    int x()  
    {  
        return mX;  
    }  
    int y()  
    {  
        return mY;  
    }  
}  
  
void main(string[] args)  
{  
    writefln("D Demo");           // D Demo  
      
    Point p = new Point(1, 2);  
      
    writefln(p.name());           // Point  
    writefln(p.info());           // P(1, 2)  
} 

test2.cs

class Obj  
{  
    protected string mName;  
    protected string mInfo;  
      
    public Obj()  
    {  
        mName = "Object";  
        mInfo = "";  
    }  
      
    public string name()  
    {  
        return mName;  
    }  
      
    public string info()  
    {  
        return mInfo;  
    }  
}  
  
class Point : Obj  
{  
  
    private int mX;  
    private int mY;  
  
    public Point(int x, int y)  
    {   
        mX = x;  
        mY = y;  
        mName = "Point";  
        mInfo = "P(" + mX + ", " + mY + ")";  
    }  
      
    public int x()  
    {  
        return mX;  
    }  
      
    public int y()  
    {  
        return mY;  
    }  
}  
  
class Program  
{  
    public static void Main(string[] args)  
    {  
        System.Console.WriteLine("C# Demo");    // C# Demo  
          
        Point p = new Point(1, 2);  
          
        System.Console.WriteLine(p.name());     // Point  
        System.Console.WriteLine(p.info());     // P(1, 2)  
          
    }  
}  

test3.java

class Obj  
{  
    protected String mName;  
    protected String mInfo;  
      
    public Obj()  
    {  
        mName = "Object";  
        mInfo = "";  
    }  
      
    public String name()  
    {  
        return mName;  
    }  
      
    public String info()  
    {  
        return mInfo;  
    }  
}  
  
class Point extends Obj  
{  
  
    private int mX;  
    private int mY;  
  
    public Point(int x, int y)  
    {   
        mX = x;  
        mY = y;  
        mName = "Point";  
        mInfo = "P(" + mX + ", " + mY + ")";  
    }  
      
    public int x()  
    {  
        return mX;  
    }  
      
    public int y()  
    {  
        return mY;  
    }  
}  
  
class Program {  
    public static void main(String[] args){  
        System.out.println("Java Demo");    // Java Demo  
          
        Point p = new Point(1, 2);  
          
        System.out.println(p.name());       // Point  
        System.out.println(p.info());       // P(1, 2)  
    }  
}  

4、小结

继承是面向对象中类之间的—种关系 

子类拥有父类的所有属性和行为 

子类对象可以当作父类对象使用 

子类中可以添加父类没有的方法和属性 

继承是面向对象中代码复用的重要手段

面向对象中的访问级别不只是public和private 

protected修饰的成员不能被外界所访问 

protected使得子类能够访问父类的成员 

protected关键字是为了继承而专门设计的 

没有protected就无法完成真正意义上的代码复用

C++中支持3种不同的继承方式 

继承方式直接影响父类成员在子类中的访问属性 

一般而言,工程中只使用public的继承方式 

C++的派生语言中只支持public继承方式

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页