一、在继承方式的不同
(1)python中类的继承没有派生列表的访问说明符,如单一继承时,有如下继承方式:
class Animal(object):
def run():
print("Animal run!")
class Dog(Animal):
pass
Dog类继承了Animal类,直接在类名后的括号内写入要继承的类名即可。
(2)C++中类的继承含有派生列表的访问说明符,如:
class Animal
{
public:
Animal() = default;
virtual void run () {cout << "Animal run!" << endl;}
protected:
virtual ~Animal() = default;
};
class Dog: public/protected/private(任选一个) Animal
{
public:
Dog() = default;
};
Dog继承自Animal类,Animal称为基类,Dog称为派生类,在C++中继承父类时,需指定特定的派生列表的访问说明符,其影响着用户对基类成员的访问权限。
二、多态上的不同
(1)python为动态语言,其多态的要求上非常宽松,对于如下例子:
class Animal(object):
def run():
print("Animal run!")
class Dog(Animal):
def run():
print("Dog run!")
class Cat(object):
def run():
print("Cat run!")
def run_twice(animal):
animal.run()
animal.run()
a = Animal()
d = Dog()
c = Cat()
run_twice(a) ## result --> Animal run!
# Animal run!
run_twice(d) ## result --> Dog run!
# Dog run!
run_twice(c) ## result --> Cat run!
# Cat run!
在此例中,对于run_twice的调用,以上定义的三种类的对象均可以被调用,即只要对应的类定义了run同名的成员函数,即可调用,而C++中的多态指的是只有子类以及自身可以调用。
(2)C++中多态要求较为严格,首先为支持多态,在基类中需要将支持多态的函数定义为虚函数(virtual),其派生类对应的函数也为虚函数,而不需重新指定。其次,为使用多态特性,需要通过基类的指针或引用来进行调用,例:
class Animal
{
public:
Animal() = default;
virtual void run () {cout << "Animal run!" << endl;}
protected:
virtual ~Animal() = default;
};
class Dog: public Animal
{
public:
Dog() = default;
void run() {cout << "Dog run!" << endl;}
};
void run_twice(Animal& a)
{
a.run();
a.run();
}
// or
//void run_twice(Animal* a)
//{
// a->run();
// a->run();
//}
int main()
{
Animal a;
Dog d;
run_twice(a); // run_twice(Animal& a);
run_twice(d);
}
results:
Animal run!
Animal run!
Dog run!
Dog run!
三、属性与方法的定义上
(1)python为动态语言,其类的属性与方法可以动态添加,如若想将某几个属性与类绑定,则可以在__init__成员函数中创建,例:
class Student(object):
count = 0 # 类属性,被所有实例所共享
def __init__(self, name, score):
self.name = name
self.score = score
s = Student("张三", 18)
print(s.name, " ", s.score)
s.gender = "man" ## 动态添加实例属性
s.count = 20 ## 由于实例属性的优先级大于类属性,故同名的实例属性会遮挡类属性,但是类属性并没有消失
print(Student.count) ## 当类属性被遮挡,通过类名即可访问类属性
def set_age(self, value):
self.age =value
## 采用types.MethodType为类实例添加方法
s1 = Student("李四",99)
s1.set_age = MethodType(set_age, s1)
s1.set_age(18)
s1.age ## 18
## 注意实例的方法添加不可以直接通过s1.set_age = set_age添加,与属性不同
## 为一个实例绑定的属性与方法在其他实例上不适用
s2 = Student("王五", 100)
s2.set_age(18) ## s2没有该方法
## 若想使其他实例也具有某属性或方法,则可以为类添加属性或方法
Student.father = "zwk"
Student.set_age = set_age ## 为类提供方法可以直接赋值
(2)而C++中的类成员,必须在定义时确定