**C++和JAVA中的多态区别以及与此相关的重载、覆盖和隐藏*


*
在C++中:
重载的条件:

  1. 同一类中;
  2. 函数名称相同;
  3. 参数不同,包括个数和类型;
  4. virtual可有可无。

覆盖的条件:

  1. 派生类—-> 基类;
  2. 函数名相同;
  3. 参数相同,包括个数和类型;
  4. 基类函数有virtual修饰。

隐藏:派生类屏蔽了与其同名的基类函数

  1. 如果派生类的函数名和基类相同,但是参数不同,此时无论有无virtual修饰,基类的函数被隐藏;
  2. 如果派生类与基类函数名相同,而且参数也完全相同,但是基类的函数没有virtual修饰,则基类的函数被隐藏。

JAVA中:

  1. 同名的实例方法被覆盖(参数也完全一样)(多态的实现),同名的静态方法被隐藏;
  2. 覆盖和隐藏的区别在于,子类对象转换为父类对象后可以访问父类的被隐藏的方法,而不能访问被覆盖的方法;
  3. 在java中,在还未初始化子类的时候,子类的同名函数就已经覆盖父类的了;(有相应的博客说过这个问题)
  4. 成员属性只能被隐藏,不能被覆盖。

先上代码:
C++代码:

class A{
public:
    virtual void foo1()
    {
        cout<<"在A中foo1()..."<<endl;
    }
    void foo2(int a)
    {
        cout<<"在A中foo2(int a)   "<<a<<endl;
    }
    virtual void foo3(int a)
    {
        cout<<"在A中foo3(int a)   "<<a<<endl;
    }
    void foo4(int a)
    {
        cout<<"在A中foo4(int a)   "<<a<<endl;
    }
};

class B :public A{
public :
    void foo1()
    {
        cout<<"在B中foo1()..."<<endl;
    }
    void foo2(char a)
    {
        cout<<"在B中foo2(char a)   "<<a<<endl;
    }
    void foo3(char a)
    {
        cout<<"在B中foo3(char a)   "<<a<<endl;
    }
    void foo4(int a)
    {
        cout<<"在B中foo4(int a)   "<<a<<endl;
    }
    void foo5()
    {
        cout<<"foo5..."<<endl;
    }
};
int _tmain(int argc, _TCHAR* argv[])
{
    A  *ptr = new B();
    ptr->foo1();        //多态,输出子类函数
    ptr->foo2(100);     //
    ptr->foo2('a');
    ptr->foo3(100);
    ptr->foo3('b');
    ptr->foo4(100);
    ((B*)ptr)->foo5();
}

这里写图片描述

分析:

  1. 基类的foo1()函数是被正确的重载了,所以输出的是派生类的实现;
  2. 按定义foo2()被隐藏,ptr是指向A的指针,所以输出的是基类的实现;
  3. 同样,foo3()被隐藏,ptr是指向A的指针,所以输出的是基类的实现;
  4. foo4()同上;
  5. 如果派生类新增了成员函数,则必须将基类的指针ptr强制转换成派生类对象才能调用;

如果把main函数中的A *ptr = new B(); 改成 B *ptr = new B();结果如下:
这里写图片描述
分析:

  1. foo1()多态的体现;
  2. 基类的foo2(),foo3(),foo4()均被隐藏,派生类的指针ptr访问不到;

java代码:

class A{
    public void foo1()
    {
        System.out.println("在A中foo1()");
    }
    public void foo2(int a)
    {
        System.out.println("在A中foo2(int a)   "+a);
    }
    public void foo3(int a)
    {
        System.out.println("在A中foo3(int a)   "+a);
    }
    public static void foo4(int a)
    {
        System.out.println("在A中foo4(int a)   "+a);
    }
};
class B extends A{
    public void foo1()
    {
        System.out.println("在B中foo1()...");
    }
    public void foo2(char a)
    {
        System.out.println("在B中foo2(char a)   "+a);
    }
    public void foo3(char a)
    {
        System.out.println("在B中foo3(char a)   "+a);
    }
    public static void foo4(int a)
    {
        System.out.println("在B中foo4(int a)   "+a);
    }
};
public class wang {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        A ptr = new B();
        ptr.foo1();     //多态,输出子类函数
        ptr.foo2(100);      //
        ptr.foo2('a');
        ptr.foo3(100);
        ptr.foo3('b');
        ptr.foo4(100);
        A a=ptr;
        a.foo4(10);
    }
}

这里写图片描述

  1. foo1()是多态的实现,访问的是子类的实现;
  2. 父类的foo2(),foo3()均没有被子类覆盖,ptr是父类对象,所以访问的是父类的实现;
  3. foo4()属于同名的静态方法被隐藏,ptr是父类对象,所以访问的是父类的实现;

如果把主方法中的A ptr = new B(); 改成 B ptr = new B();结果为:
这里写图片描述

  1. 发现相同的代码在C++中和在java中的结果完全不一样;
  2. 父类的foo2()和foo3()没有被覆盖,当然也不是被隐藏,所以可以理解为它们在子类中和子类中对应的方法一同以重载出现,根据参数的不同,调用对应的方法;

关于面向对象的编程,主要三个方面就是封装、继承、多态。语言教程看了很多遍,但不久后便忘记。原因就是应用的少,没有在实战中提升对它们的深刻理解。
肯定有一些不准确的地方,待以后慢慢改正。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值