Java教程

继承和多态

本文主要是介绍继承和多态,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

继承:

        类与类之间的关系

组合类:

            一个类是另一个类的一部分

            例:head  ---   {eye,nose}

 

代理类:

            一个类中的方法是另一个类方法的子集

            例:list --- >  stack

继承:

           一个类是另一个类的一种

          例:动物  ---->  猫 狗..

三种访问属性:

                1:可访问 0:不可访问

                外界              子类             自身
public:        1                    1                 1
protected:   0                    1                 1
private:       0                    0                 1

继承的写法:

在子类的类定义后面加上 : 父类名字

继承权限:

public:
protect:
private:

默认继承权限是private

class A
{
public:
    int a;
    void fun1()
    {
        cout << "public  void fun1() " << endl;
    }

protected:
    int b;
    void fun2()
    {
        cout << "protected  void fun2() " << endl;
    }
private:
    int c;
    void fun3()
    {
        cout << "private  void fun3() " << endl;
    }
};

继承权限限制的是子类继承父类之后,父类的成员在子类中的最低访问权限

如果采用private的方式继承,则会将父类中的public和protected放在子类中的private
子类中可以访问,外界不可访问

 

采用public继承时,private继承不下来

class B :public A
{
public:
   
    int a;
    void fun1()
    {
        cout << "public  void fun1() " << endl;
    }
   
    int a1;
protected:
   
    int b;
    void fun2()
    {
        cout << "protected  void fun2() " << endl;
    }
   
    void fun_tmp()
    {
        cout << a << endl;//A::public
        cout << b << endl;//A::protected
        //cout << c << endl;//A::private
    }
    int b1;
private:
    /*


    */
    int c1;
};

采用protected继承时,只能继承protected

class B :protected A
{
public:
    
    int a1;
protected:
    
    int b;
    void fun2()
    {
        cout << "protected  void fun2() " << endl;
    }
    
    void fun_tmp()
    {
        cout << a << endl;//A::public
        cout << b << endl;//A::protected
        //cout << c << endl;//A::private
    }
    int b1;
private:
    /*


    */
    int c1;
};

采用private时,一个都继承不了(相当于私有继承)

class B :private A
{
public:
    
    int a1;
protected:
    

    int b1;
private:
    /*


    */
    int c1;
};

继承方式一般采用public

函数之间的关系

重载

继承中成员方法的关系

隐藏

子类中的成员方法会隐藏父类中同名的成员方法    ------   同名隐藏

访问被隐藏的父类成员方法使用父类作用域即可

覆盖

 

类的构造顺序:

组合类:

class A{}

class B

{

B():A(){}

A a;

}

B b;

先构造成员对象  ---》 再构造自身对象

先析构自身对象----》再析构成员对象

 

继承类:

先构造父类 ---- 》再构造子类   ------子类的构造函数一定在初始化列表进行了父类的构造

先析构子类 -----》再析构父类

如果类中存在必须再自身构造之前需要完成的事情,就一定要在初始化列表中完成

 

#include<string>
class Animal
{
public:
    Animal(const string& name)
        :_name(name)//初始化列表
    {
        cout << "Animal(const string& name)" << endl;
    }
    void eat()
    {
        cout << _name << "  eat eat eat……" << endl;
    }
    void run()
    {
        cout << _name << "  walk  walk  walk……" << endl;
    }
    ~Animal()
    {
        cout << "~Animal()" << endl;
    }
protected:
    const string _name;
};


class Cat : public Animal
{
public:
    Cat(const string& name)
        :Animal(name)
    {
        cout << "Cat(const string& name)" << endl;
    }

    void sleep()
    {
        cout << _name << "  sleep  sleep sleep ……" << endl;
    }

    void eat(int a)//同名隐藏
    {
        cout << _name << "  eat fish……" << endl;
    }
    ~Cat()
    {
        cout << "~Cat()" << endl;
    }

    /*
    void eat()
    {
        cout << _name << "  eat eat eat……" << endl;
    }
    void run()
    {
        cout << _name << "  walk  walk  walk……" << endl;
    }
    */
};
int main()
{
    Cat cat("cat");

    //cat.eat();
    //cat.Animal::eat();
    //Animal a("ss");


    return 0;
}

覆盖

虚函数:

virtual修饰的成员方法就是虚函数

 

.text

.data  .bss

.rodata---只读数据段 read only data    虚函数表存放在rodata段

虚函数的调用

对象调用

直接取text段调用对应的函数指令

对象指针调用

会先去虚函数表中找到对应的虚函数指针

再去text段中虚函数指针对应的位置调用找到的函数

virtual存在继承性

比如父类中为 virtual void fun1()   子类中为  void fun1()

则子类中的fun1同样会被处理为virtual

 

虚函数在继承中存在覆盖的可能性

覆盖的条件:

1.父类中的成员方法必须是虚函数

2.子类中成员方法和父类中成员方法相同---(函数名相同,参数列表相同,返回值相同)

 

如果多个父类中存在虚表,继承之后子类中就会有多个虚表

class Base2
{
public:
    int b;
    virtual void fun5()
    {
        cout << "Base2::fun5()" << endl;
    }
    virtual void fun6()
    {
        cout << "Base2::fun6()" << endl;
    }

    virtual void fun()
    {
        cout << "Base2::fun()" << endl;
    }
};

class Base
{
public:
    int a;
    virtual void fun1()
    {
        cout << "Base::fun1()" << endl;
    }
    virtual void fun2()
    {
        cout << "Base::fun2()" << endl;
    }

    void fun3()
    {
        cout << "Base::fun3()" << endl;
    }

    virtual void fun()
    {
        cout << "Base::fun()" << endl;
    }
};

class Drive : public Base2, public Base
{
public:
    void fun1()
    {
        cout << "Drive::fun1()" << endl;
    }

    void fun5()
    {
        cout << "Drive::fun5()" << endl;
    }

    virtual  void fun4()
    {
        cout << "Drive::fun4()" << endl;
    }

    void fun()
    {
        cout << "Drive::fun()" << endl;
    }
    int c;
};

typedef void(*TYPE_FUN)();

void printf_vftable(TYPE_FUN* table)
{
    for (int i = 0; table[i] != NULL; i++)
    {
        cout << "[" << i << "]" << table[i] << endl;
        table[i]();
    }
}


int main()
{
#if 0
    cout << sizeof(Base) << endl;
    Base tmp1;

    /*
    Drive tmp2;
    tmp2.fun1();
    tmp2.Base::fun1();
    */

    //父类指针指向子类对象
    Drive* p = new Drive();
    p->fun1();
    p->Base::fun1();

    Drive tmp2;
#endif

    //Base tmp1;
    //Base* tmp = &tmp1;
    //printf_vftable(((TYPE_FUN**)tmp)[0]);
    Drive tmp2;
    Base* tmpp = &tmp2;
    //printf_vftable(((TYPE_FUN**)tmpp)[0]);
    tmpp->fun();
    return 0;
}

 

函数之间的关系重载

继承中成员方法的关系隐藏子类中的成员方法会隐藏父类中同名的成员方法    ------   同名隐藏访问被隐藏的父类成员方法使用父类作用域即可


覆盖

 

这篇关于继承和多态的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!