zoukankan      html  css  js  c++  java
  • C++03:封装->继承->多态

    一.简介

    1.可维护

    2.可复用

    3.可扩展

    4.灵活性好

    面向对象的设计思想就是通过封装 继承 多态把程序的耦合性降低,使得程序更加的灵活,容易修改,并且易于复用

    面向对象的五大基本原则

    1.单一职责原则(SRP)

    2.开放封闭原则(OCP)

    3.里氏替换原则(LSP)

    4.依赖倒置原则(DIP)

    5.接口隔离原则(ISP)

    函数编程

    泛型编程

    元编程

     

    二.封装

    class A{
      
    public:
        A(int a){
      
        }
    }

    1.重载(Overload)

     成员被重载的特征:(1)相同的范围,在同一个类中

                                     (2)函数名字相同

                                     (3)参数不同

    2.抽象类和纯虚函数

    纯虚函数是在基类声明的虚函数(加上 =0),它在基类中没有定义,但是要求派生类都要实现自己的实现方法

    包含纯虚函数的类称为抽象类

    (1) 抽象类只能用作其他类的基类,不能定义抽象类的对象

    (2) 抽象类不能用于参数类型 函数返回值 或 显示转换的类型

    (3) 抽象类可以定义抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性

    三.继承

    class B: public A{
    public:
        B(int a,int b):A(a){
      
        }
    };
      
    class C:public A{
    public:
        C(int a,int c):A(a){
         
        }
    };
      
    //C++允许多继承
    class D:public B,public C{
    public:
        D(int a,int b,int c):B(a,b),C(a,c),A(a){
      
        }
         
    };

    1.继承的调用顺序

    #pragma  once
    
    #include <iostream>
    using namespace std;
    
    class F{
    
    public:
        F(){ k5 = 10;  cout << "F:F()" << endl; }
        ~F(){ cout << "F:~F()" << endl; }
        //virtual ~F(){}
    
        void FuncA(){ cout << "F:FuncA()" << endl; }
        virtual void FuncB() { cout << "F::FuncB()" << endl; }
        int k5;
    
    protected:
        int k4;
    
    };
    
    class Z : public  F{
    
    public:
        Z(){ k5 = 5; cout << "Z:Z()" << endl; }
        ~Z(){ cout << "Z:~Z()" << endl; }
        
    
        void FuncA(){ cout << "Z::FuncA()" << endl; }
        void FuncB() { cout << "Z::FuncB()" << endl; }
        int k5;
        
    protected:
        int k4;
    
    };
    #include "Jicheng.h"
    
    int main()
    {
        F* a = new F();  //F()
        cout << endl;
    
        F* a1 = new Z();  //F() Z()
        cout << endl;
    
        Z* a2 = new Z();  //F() Z()
        cout << endl;
    
        //Z* a3 = new F();  错误
    
        a->FuncA();  //F:FunA()
        a1->FuncA();  //F:FunA()
        a2->FuncA();  //Z:FunA()  如果子类没有相应的函数,那么会调用父类的函数
    
        a->FuncB();  //F:FunB()
        a1->FuncB();  //Z:FunB()
        a2->FuncB();  //Z:FunB()
    
        int k5 = a->k5;  //10
        int k4 = a1->k5;  //10
        int k3 = a2->k5;  //5
    
        //int k55 = a->k4;  k4是保护成员,无法访问
    
        delete a;  //~F()
        cout << endl;
    
        delete a1;  //如果父类析构函数加virtual 那么会多一个子类的析构函数 ~Z()  ~F() 
        cout << endl;
    
        delete a2;  //~Z()  ~F()
        cout << endl;
    
    
        system("pause");
    
        return 0;
    }

    2.继承的访问权限

    (1)类继承访问权限

    父类的private成员无法被继承

    (1)public继承:父类的public/protected成员继承到子类的访问权限不变

    (2)private继承:父类的public/protected成员继承到子类变为private

    (3)protected继承:父类的public/protected成员继承到子类变为protected

    (2)成员访问权限

    (1)private:①能被基类函数 ②能被友元函数 访问,无法被基类对象访问

    (2)protected:①能被基类函数 ②能被友元函数 ③能被子类函数 访问,无法被基类对象访问

    (3)public:①能被基类函数 ②能被友元函数 ③能被子类函数 ④能被基类对象

     

    3.继承的隐藏规则

    隐藏是指派生类的函数屏蔽了与其同名的基类函数。注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏

    四.多态

    1.虚函数(覆盖,Override)

    覆盖是指派生类函数覆盖基类函数,特征:(1)不同范围,分别位于派生类和基类

                                                                         (2)函数名字相同

                                                                         (3)参数相同

                                                                         (4)基类函数必须有virtual关键字

    主要是实现了多态的机制,简而言之就是用父类(基类)的指针指向子类(派生类)的对象,然后通过父类(基类)的指针调用不同子类(派生类)的对象的不同函数,这就是一种泛型.

    一个公有派生类对象可以赋值给基类的对象,但是基类的对象不能赋值给派生类的对象

    虚函数一般用于基类成员函数来绑定派生类成员函数一起调用

    默认情况下成员函数不能动态绑定,但是添加virtual函数(虚函数)可以让函数有晚绑定的灵活性

    2.虚函数的使用

    //1.在基类用virtual声明成员函数为虚函数,
    class Base{
      
        virtual void A();
    };
      
    //在类外定义虚函数无需加virtual
    void Base::A(){
      
    }
      
    //2.在派生类重新定义虚函数,要求函数名/函数类型/函数参数的类型和个数保持一致
    class Derive : pubic Base{
      
        //虚函数在派生类重新声明时,无需加virtual
        void A();
    };
      
    //3.定义一个指向基类对象的指针变量,并使用基类对象的指针变量指向不同的派生类对象的函数
    void main(){
        Base* p=new Derive();
        p->A();
    }
    class Base {
    public:
        Base() {echo();}
        virtual void echo() {printf(“Base”);}
    };
       
    class Derived:public Base {
    public:
        Derived() {echo();}
        virtual void echo() {printf(“Derived”);}
    };
       
    int main() {
        Base* base = new Derived();
        base->echo();  //输出Base Derived  Derived
        return 0;
    }

    3.动态绑定技术

    #include <iostream>
    using namespace std;
    class A
    {
    public:
        virtual void func(int val = 1)
        {
            std::cout " << val << std::endl;
        }
        virtual void test()
        {
            func();
        }
    };
    class B : public A
    {
    public:
        void func(int val = 0)
        {
            std::cout " << val << std::endl;
        }
    };
    int main(int argc, char* argv[])
    {
        A*p1 = new A;
        A*p2 = new B;
        //B*p3 = new A;    //error
        B*p3 =  reinterpret_cast<B*> (new A);
        B*p4 = new B;
        //测试test()
        p1->test();    //A->1
        p2->test();    //B->1
        p3->test();    //A->1
        p4->test();    //B->1
        //测试func()
        p1->func();    //A->1
        p2->func();    //B->1
        p3->func();    //A->0
        p4->func();    //B->0
        return 0;
    }
    #include <iostream>
    using namespace std;
    class A
    {
    public:
        void func(int val = 1)
        {
            std::cout " << val << std::endl;
        }
        //这个test()的virtual可有可无
        virtual void test()
        {
            func();
        }
    };
    class B : public A
    {
    public:
        void func(int val = 0)
        {
            std::cout " << val << std::endl;
        }
    };
    int main(int argc, char* argv[])
    {
        A*p1 = new A;
        A*p2 = new B;
        //B*p3 = new A;    //error
        B*p3 = reinterpret_cast<B*> (new A);
        B*p4 = new B;
        //test()
        p1->test();    //A->1
        p2->test();    //A->1
        p3->test();    //A->1
        p4->test();    //A->1
                       //func()
        p1->func();    //A->1
        p2->func();    //A->1
        p3->func();    //B->0
        p4->func();    //B->0
        return 0;
    }

    4.虚析构函数

    虚析构函数的作用是delete动态对象时释放资源

    //test.h
    class A{
      
    public:
        char* strA;
        A(char* a){
      
            strA=new char[12];
            strncpy(strA,a,strlen(a));
        }
        virtual  ~A(){  //不加virtual会报错
            delete strA;
        }
    };
      
    class B:public A{
      
    public:
        char* strB;
        B(char* a):A(a){
      
            strB=new char[12];
            strncpy(strB,a,strlen(a));
        }
        ~B(){
            delete strB;
        }
    };
      
    //test.cpp
    int main(){
      
        char input[]="Hello";
        A* a=new B(input);
        delete[] a;
      
          
        system("pause");
      
        return 0;
    }
  • 相关阅读:
    Java对于私有变量“反思暴力”技术
    图形界面汇总
    【j2ee spring】27、巴巴荆楚网-整合hibernate4+spring4(2)
    .net Work Flow 4.0
    Drainage Ditches
    Google 开源项目的风格指南
    2015第53周一
    2015第52周日
    2015第52周六
    2015第52周五
  • 原文地址:https://www.cnblogs.com/k5bg/p/11691615.html
Copyright © 2011-2022 走看看