21、继承
class Parent
{
public:
Parent(int value){this->value=value;}
private:
int value;
};
class Child : public Parent
{
public:
Child(int value):
Parent(value),
c('0')//不能将父类parent的value属性这样初始化。value初始化只能如上句调用父类构造函数、或者在下面的函数体内初始化
{}
private:
char c;
};
22、隐藏
在c++中,如果子类隐藏了父类的函数,则父类中的所有同名函数都会被隐藏!!!
#include<iostream>
class Parent
{
public:
Parent(){}
Parent(int value){this->value=value;}
~Parent(){}
Parent(Parent&){}
void move(){std::cout《"Parent moves "《value《" step!"《std::endl;}
void move(int n){std::cout《"Parent moves "《n《" step!"《std::endl;}
protected:
int value;
};
class Child: public Parent
{
public:
Child(){}
Child(int value,int special):
Parent(value),
special(special)
{
}
void move(){std::cout《"Child moves "《value《" step!"《std::endl;}
private:
int special;
};
void main()
{
Child *c=new Child(2,3);
c->move(2);//error!!!因为父类中所有名字为move的函数都已经被隐藏,子类已经没有move(int)方法,但可以用父类调用
Parent *p;
p->move(3);//right!!!
}
在java中,如果子类隐藏了父类的函数,则父类中的其他同名函数不会被隐藏!!!下面是java代码
public class Parent {
protected int value;
public Parent() {
}
Parent(int value) {
this.value = value;
}
public void move() {
System.out.println("parent moves " + value + " steps!");
}
public void move(int n) {
System.out.println("parent moves " + n + " steps!");
}
}
public class Child extends Parent {
Child() {
super();
}
Child(int value) {
super(value);
}
public void move() {
System.out.println("child moves " + value + " steps!");
}
public static void main(String[] args) {
Child child=new Child(1);
child.move(2);//right!!!
}
}
23、多态
要实现多态,就要声明为虚函数virtual,这与java是有区别的(java不需要声明virtual)。
class Parent
{
public:
Parent(int value){this->value=value;}
virtual void function(){}
private:
int value;
};
class Child : public Parent
{
public:
Child(int value):
Parent(value),
c('0')//不能将父类parent的value属性这样初始化。value只能如上句,或者在下面的函数体内初始化
{}
void function(){std::cout《"test"《std::endl;}
private:
char c;
};
24、在多态的使用中,只有通过指针和引用进行调用时,才能发挥虚函数的魔力;按值传递对象时不能发挥虚函数魔力。按值传递只能够保留父类的方法,切除子类特有方法。
#include<iostream>
class Parent
{
public:
Parent(){}
Parent(int value){this->value=value;}
~Parent(){}
Parent(Parent&){}
virtual void move(int n){std::cout《"Parent moves "《n《" step!"《std::endl;}
protected:
int value;
};
class Child: public Parent
{
public:
Child(){}
Child(int value,int special):
Parent(value),
special(special)
{
}
void move(int n){std::cout《"Child moves "《n《" step!"《std::endl;}
private:
int special;
};
void main()
{
Parent *p = new Child(1,1);
p->move(1);//输出child moves 1 step!
Parent& p1 = *p;
p1.move(1);//输出child moves 1 step!
Parent p2 = *p;
p2.move(1);//输出Parent moves 1 step!,即子类的方法被切除,调用父类方法
delete p;
}
25、 如果将基类指针赋给子类,就用到了dynamic_cast,它确保转换是安全的。在运行阶段检查基类指针,如果可以转换,就转化为子类指针,如果不能,子类指针为空NULL.
26、C++中用纯虚函数来支持抽象数据类型ADT,抽象类和函数。java中用abstract关键字。
任何包含一个或多个纯虚函数的类都是ADT,不能对其实例化,试图这样做将导致编译错误。
a、不能创建这个类的对象,只能从其派生
b、务必重写从这个类继承的纯虚函数
#include<iostream>
class Parent
{
public:
Parent(){}
Parent(int value){this->value=value;}
~Parent(){std::cout《"destructor"《std::endl;}
Parent(Parent&){}
virtual void move()=0;
protected:
int value;
};
class Child: public Parent
{
public:
Child(){}
Child(int value,int special):
Parent(value),
special(special)
{
}
void move(){std::cout《"Child moves "《value《" step!"《std::endl;}
private:
int special;
};
void main()
{
Parent *p = new Parent(1);//error!!!,不能创建ADT的对象
Child *c = new Child(1,1);//子类实现了纯虚函数,可以创建对象
c->move();
}