继承
继承是面向对象程序设计的重要特征,也是实现“代码复用”的重要手段 已有的类称为“父类或者基类”,新的类称为“子类或者派生类”
class 子类类名(父类1[,父类2,……]):
类体
如果在类定义中没有指定父类,则默认父类是object类。也就是说,object是所有类的父类,里面定义了一些所有类共有的默认实现,比如:new() 定义子类时,必须在其构造函数中调用父类的构造函数,格式如下:
父类名._init_(self,参数列表)
class Person:
def _init_(self,name,age):
self.name=name
self.age=age
def say_age(self):
print("年龄不知道")
class Student(Person):
def _init_(self,name,age,score):
Person._init_(self,name,age)
self.score=score
print(Student.mro())
s=Student("wwj",10,60)
s.say_age()
print(s.name)
类成员的继承和重写
1、成员继承:子类继承父类的构造方法之外的所有成员 2、方法重写:子类可以重新定义父类中的方法,这样就会覆盖父类的方法,也称为“重写”
查看类的继承层次结构
通过类的方法mro()或者类的属性_mro_可以输出这个类的继承层次
class A:pass
class B(A):pass
class C(B):pass
print(C.mro())
object根类
object类是所有类的父类,因此所有类都有object类的属性和方法。
dir()查看对象属性
方便的看到指定对象的所有属性
class Person:
def _init_(self,name,age):
self.name=name
self.age=age
def say_age(self):
print(self.name,'的年龄是:',self.age)
obj=object()
print(dir(obj))
p2=Person('wwj',10)
print(dir(p2))
从上面结果可以发现: 1、Person对象增加了六个属性: dict module weakref age name say_age 2、object的所有属性,Person类作为object子类,显然包含所有的属性 3、我们打印age、name、say_age,发现say_age虽然是方法,实际上也是属性。只不过这个属性的类型是“method”而已
重写_str_()方法
object有一个_str_()方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用到print()方法,帮助我们查看对象的信息,str()可以重写
class Person:
def _init_(self,name):
self.name=name
def _str_(self):
return "名字是:{0}".format(self.name)
p=Person('wwj')
print(p)
多重继承
Python支持多重继承,一个子类可以有多个“直接父类”。这样,就具备了“多个父类”的特点。但由于,这样会被“类的整体层次”搞复杂,尽量避免使用
mro()函数
Python支持多继承,如果父类中有相同名字的方法,在子类没有指定父类名时,解释器将“从左向右”按顺序搜索 mro:方法解析顺序。可以通过mro()方法获得“类的层次结构”,方法解释顺序也是按照这个“类的结构层次”寻找的
super()获得父类定义
在子类中,如果想要获得父类的方法时,可以通过super()来做 super()代表父类的定义,不是父类对象
class A:
def say(self):
print('A',self)
class B(A):
def say(self):
super().say()
print('B',self)
B().say()
多态
多态是指同一个方法调用由于对象不同可能会产生不同的行为。 关于多态要注意一下2点: 1、多态是方法的多态,属性没有多态 2、多态的存在有2个必要条件:继承、方法重写
class Man:
def eat(self):
print("吃饭")
class Chinese(Man):
def eat(self):
print("筷子")
class English(Man):
def eat(self):
print("刀叉")
def manEat(m):
if isinstance(m,Man):
m.eat()
else:
print("不吃")
manEat(Chinese())
manEat(English())
特殊方法和运算符重载
Python的运算符实际上上通过调用对象的特殊方法实现的。
a=20
b=30
c=a+b
d=a._add_(b)
print("c=",c)
print("d=",d)
'''
运行结果:
a=50
b=50
'''
常见的特殊方法统计如下:
方法 | 说明 | 例子 |
---|
init | 构造方法 | 对象创建:p=Person() | del | 析构方法 | 对象回收 | repr,str | 打印,换行 | print(a) | call | 函数调用 | a() | getattr | 点号运算 | a.xxx | setattr | 属性赋值 | a.xxx=value | getitem | 索引运算 | a[key] | setitem | 索引赋值 | a[key]=value | len | 长度 | len(a) |
每个运算符实际上都对应了相应的方法:
运算符 | 特殊方法 | 说明 |
---|
运算符+ | add | 加法 | 运算符- | sub | 减法 | <,<=,== | lt,le,eq | 比较运算符 | >,>=,!= | gt,ge,ne | 比较运算符 | l,^,& | or,xor,and | 或,异或,与 | <<,>> | lshift,rshift_ | 左移,右移 | *,/,%,// | mul,truediv,mod,floordiv | 乘,浮点除,模运算(取余),整数除 | ** | pow | 指数运算 |
|