Java与C++在面向对象中的一些异同

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43946347/article/details/102733055

C++与Java小谈


C++ ------------- Java

虚函数 -------- 普通函数
纯虚函数 -------- 抽象函数
抽象类 -------- 抽象类
虚基类 -------- 接口


虚函数定义:在某基类中声明为 virtual 并在一个或多个派生类中被重新定 义的成员函数,用法格式为:virtual 函数返回类型 函数名(参数表) {函数体};实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数。----(百度百科)

#include<iostream>
using namespace std;
class A
{
    public:
        void virtual FUN()
        {
            cout<<"FUN in A is called"<<endl;
        }
};
 
class B : public A
{
    public:
        void FUN()
        {
            cout<<"FUN in B is called"<<endl;
        }
};
 
int main()
{
    A a;
    B b;
    A *p;
    p = &a;
    p->FUN();
    p = &b;
    p->FUN();
    return 0;
}

运行结果

FUN in A is called
FUN in B is called

若去掉virtual后,运行结果变为

FUN in A is called
FUN in A is called

即定义了一个基类指针指向不同的对象,来实现多态性。

C++中,如果函数不是虚函数,则调用某个函数,是根据当前指针类型来判断的,并不是根据指针所指向对象的类型。

在Java中,如果函数不是抽象函数,而是一个普通函数,它是默认实现类似C++中虚函数功能的,也就是说,调用某个函数,是根据当前指针所指向对象的类型来判断的,而不是根据指针类型判断。正好与C++中的普通函数相反。即:JAVA里自动实现了虚函数。

例如:

package Virtual;

public class VirtualTest {
	public static void main(String args[])  {
        A a = new A();
        B b = new B();
        A p;
 
        p = a;
        p.FUN();
        p = b;
        p.FUN();
    }
}
class A{
	public void FUN(){
        System.out.println("FUN in A is called");
    }
}
class B extends A{
    public void FUN(){
        System.out.println("FUN in B is called");
    }
}

运行结果为

FUN in A is called
FUN in B is called

纯虚函数与抽象类

定义:纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”。

virtual void funtion1()=0

定义纯虚函数的目的在于,使派生类仅仅只是继承函数的接口。
纯虚函数的意义,让所有的类对象(主要是派生类对象)都可以执行纯虚函数的动作,但类无法为纯虚函数提供一个合理的缺省实现。所以类纯虚函数的声明就是在告诉子类的设计者,“你必须提供一个纯虚函数的实现,但我不知道你会怎样实现它”。

含有纯虚函数的类就是抽象类。

抽象方法与抽象类

如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。
父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。
在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

Java语言中使用abstract class来定义抽象类。

public abstract class leiming{
---------
}

声明抽象方法的语法是

abstract <方法返回值类型><方法名>(参数列表);

包含抽象方法的一定是抽象类,但是抽象类不一定包含抽象方法


虚基类

虚基类是用关键字virtual声明继承的父类,即便该基类在多条链路上被一个子类继承,但是该子类中只包含一个该虚基类的备份,虚基类主要用来解决继承中的二义性问题,这就是是虚基类的作用所在。

正是由于虚基类的这个作用,所以在每个子类的构造函数中必须显示的调用该虚基类的构造函数,不管该虚基类是不是直接的父类。

其次,虚基类的构造函数的调用早于其他非虚基类的构造函数的调用。

上面两点就是虚基类的特性。

接口

在Java中,定一个接口的形式如下:

[public] interface InterfaceName {
}

接口中可以含有 变量和方法。
但是要注意,接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量,用private修饰会报编译错误),而方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字,比如private、protected、static、 final等修饰会报编译错误),并且接口中所有的方法不能有具体的实现,也就是说,接口中的方法必须都是抽象方法。从这里可以隐约看出接口和抽象类的区别,接口是一种极度抽象的类型,它比抽象类更加“抽象”,并且一般情况下不在接口中定义变量。

一个接口可以继承多个接口,可通过关键字extends来实现,其语法与类的继承相同,被继承的类接口称为父类接口,当有多个父类接口时,用逗号分隔。

implements子句表示类实现某个接口。一个类可以同时实现多个接口。在类体中必须要加入实现接口方法的代码。

详情可见
深入理解Java中的接口与抽象类

猜你喜欢

转载自blog.csdn.net/weixin_43946347/article/details/102733055
今日推荐