Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 虚函数和纯虚函数有什么区别?_Java_C++ - Fatal编程技术网

Java 虚函数和纯虚函数有什么区别?

Java 虚函数和纯虚函数有什么区别?,java,c++,Java,C++,可能重复: 虚拟函数和纯虚拟函数之间有什么区别?来自: 纯虚函数或纯虚方法是需要由非抽象的派生类实现的虚拟函数。包含纯虚拟方法的类称为“抽象”;它们不能直接实例化,并且只有当所有继承的纯虚拟方法都由该类或父类实现时,抽象类的子类才能直接实例化。纯虚拟方法通常有一个声明(签名)而没有定义(实现) 纯虚函数是必须由派生类重新定义的虚函数,因此通常在基类中没有实现(虽然可以提供,但由派生类通过作用域解析运算符调用;感谢@Mark Ransom和@Toolbox指出) 如果一个类有纯虚方法,它就不能被

可能重复:

虚拟函数和纯虚拟函数之间有什么区别?

来自:

纯虚函数或纯虚方法是需要由非抽象的派生类实现的虚拟函数。包含纯虚拟方法的类称为“抽象”;它们不能直接实例化,并且只有当所有继承的纯虚拟方法都由该类或父类实现时,抽象类的子类才能直接实例化。纯虚拟方法通常有一个声明(签名)而没有定义(实现)


纯虚函数是必须由派生类重新定义的虚函数,因此通常在基类中没有实现(虽然可以提供,但由派生类通过作用域解析运算符调用;感谢@Mark Ransom和@Toolbox指出)

如果一个类有纯虚方法,它就不能被实例化,因此任何从抽象类派生的类(=具有纯虚方法的类)都必须实际定义这种方法才能实例化

例如:

#include <iostream>

using std::cout;
using std::endl;

class BaseClass
{
public:

    // A "normal" virtual function which provides a default implementation
    virtual void OnlyVirtual()
    {
        cout<<"BaseClass::OnlyVirtual"<<endl;
    }

    // A "normal" pure virtual function: must be redefined, no default
    // implementation
    virtual void PureVirtual()=0;

    // A pure virtual function that provides a default implementation that can
    // be called only explicitly via scope-resolution operator
    virtual void PureVirtualWImpl()=0;
};

void BaseClass::PureVirtualWImpl()
{
    cout<<"BaseClass::PureVirtualWImpl"<<endl;
}

class Derived0 : public BaseClass
{
public:
    // Define the pure virtual function
    virtual void PureVirtual()
    {
        cout<<"Derived0::PureVirtual"<<endl;
    }

    // notice that, even if there's an implementation of PureVirtualWImpl in
    // BaseClass, since it's marked as pure, Derived0 cannot still be
    // instantiated
};

class Derived1 : public Derived0
{

public:
    // PureVirtual is already defined by the parent class Derived0

    // I must define also PureVirtualWImpl if I want to instantiate this class
    virtual void PureVirtualWImpl()
    {
        cout<<"Derived1::PureVirtualWImpl"<<endl;
    }
};

class Derived2 : public Derived1
{
public:

    // Obviously I can redefine the "normal" virtual function
    virtual void OnlyVirtual()
    {
        cout<<"Derived2::OnlyVirtual"<<endl;
    }

    // Redefine PureVirtual
    virtual void PureVirtual()
    {
        cout<<"Derived2::PureVirtual"<<endl;
    }

    // Just for fun I can redefine PureVirtualWImpl to call the base normally-
    // unaccessible implementation
    virtual void PureVirtualWImpl()
    {
        BaseClass::PureVirtualWImpl();
    }
};

void TestClass(BaseClass & C)
{
    C.OnlyVirtual();
    C.PureVirtual();
    C.PureVirtualWImpl();
}

int main()
{
    // BaseClass b; // <--- compilation error
    // Derived0 d0; // <--- compilation error
    Derived1 d1;
    Derived2 d2;
    TestClass(d1);
    TestClass(d2);
}
虚拟函数可以在派生类中重写。

纯虚函数必须在派生类中重写。具体地说,除非至少有一个派生类重写该虚拟函数,否则不能用纯虚拟函数实例化一个类。

那么在Java术语中,这是否意味着虚拟函数只是“(实例)方法”,纯虚拟函数是“抽象方法”?@biziclop,是的,但是需要在派生类中实现该方法。这就是“纯虚拟”和“虚拟”的区别@biziclop:Yes;Java中的所有方法都是虚拟的(显然,标记为
final
的方法除外),因此在讨论Java时,这个术语有些多余。然而,在C++和C语言中,它不是冗余的,默认情况下方法不是虚拟的,实际上可以在基类中提供纯虚函数的实现。派生类被强制重写,但它仍然可以使用scope操作符调用。这不一定是真的。如果需要,可以为纯虚拟函数提供一个实现,这在实践中并不常见。如果您希望在派生版本中使用实现细节,那么这可能会很有用,但您仍然希望强制所有派生类提供一个实现。@Toolbox@MarkRansom如果纯虚函数的基本实现永远不会被使用,那么您究竟为什么希望该实现成为纯虚函数的基本实现?@MarkRansom:修复了,谢谢。cpp中的纯虚函数与java中的抽象方法相同。重复的
BaseClass::OnlyVirtual
Derived0::PureVirtual
Derived1::PureVirtualWImpl
Derived2::OnlyVirtual
Derived2::PureVirtual
BaseClass::PureVirtualWImpl