一. C++中的虚函数、纯虚函数与多态
多态(polymorphism)是指可以使用父类的指针或引用来在运行时动态决定调用哪个子类的函数。在C++中,多态是通过虚函数来实现的。要使用多态,在C++中必须同时满足两个条件:第一,只有指定为虚函数的成员函数才能进行动态绑定,非虚函数不进行动态绑定;第二,必须通过基类的指针或者引用进行函数调用(不能通过基类的对象)。下面举例说明。
class BaseClass{
public:
virtual print(){ printf("Base\n"); }
};
class ConcreteClass{
public:
print(){ printf("Concrete\n"); }
};
void main(){
BaseClass p;
BaseClass *p1;
ConcreteClass p2;
p = p1; //不满足条件二
p1 = &p2;
p.print(); //由于不满足条件二,这儿调用的是基类的print();
p1->print(); //这儿调用的是子类的print();
}
纯虚函数的作用:如果一个类,我们不想让它被实例化,也就是将其作为一个抽象基类,可以为其定义一个纯虚函数。纯虚函数这样定义:
class Base{
public:
virtual void print() = 0;
}
这样,就不能创建Base类的对象了,Base类就只能作为一个抽象基类,只能被继承。
二. Java中的抽象类、接口与多态
含有抽象函数的类叫做抽象类,前边必须加关键字abstract。
抽象类不能实例化。
抽象类的子类如果不把所有的抽象函数都重写,那么它也是抽象类,必须用abstract修饰。
Java和C++不同,Java的多态不需要上边C++的那两个条件。无须virtual关键字,子类重写父类的函数,将子类的对象赋给父类对象,用父类对象调函数,则调用的是子类的版本。在运行时动态决定实际调用的是哪个函数。 就相当于Java中默认全部函数都是虚函数。而且Java没有指针,所以用父类的对象调用函数,即可以实现多态。这都和C++不同。
接口可以看做是纯粹的抽象类,每个函数都没有具体实现。
接口和抽象类都可以像C++中的基类一样,用于实现多态。
接口中可以有数据成员,但会自动转成static 和 final 的。它不能拥有成员变量。
接口既有抽象类的好处,即不能实例化,又有新的好处:支持多重继承。
何时使用接口?何时使用抽象类?
答:能用接口的时候就不要用抽象类。 如果设计类时就知道该类是用来被继承的,不能被实例化,那么优先考虑用接口。但有时候这个类中必须要有具体的函数定义或者成员变量时,那就得用抽象类了。
举个例子:
import java.util.*;
interface CanFly{
void fly();
}
interface CanSwim{
void swim();
}
class Action{
public void fly() {}
}
class Hero extends Action implements CanFly, CanSwim{
public void swim() {}
public void fly() {}
}
public class Adventure{
public static void t(CanSwim x) { x.swim(); }
public static void u(CanFly x) { x.fly(); }
public static void v(Action x) { x.fly(); }
public static void main(String[] args){
Hero h = new Hero();
t(h);
u(h);
v(h);
}
}
阅读(1285) | 评论(0) | 转发(0) |