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