文章目录
1 面向对象的三大特征
python为面向对象的设计语言,面向对象的设计语言一般具有3大特征:封装、继承、多态。
- 封装:隐藏对象的属性和实现细节,相当于将对象内部隐藏起来,只对外提供给调用方法。在python中实现封装的方法就是通过私有属性与私有方法形式实现封装。
- 继承:继承即子类继承父类代码原有的功能,继承的作用在于提高了代码的重复使用,即子类在父类代码的基础上扩展相应的功能即可。
- 多态:即一段代码不同的对象调用会有不同的行为。
2 继承
2.1 语法格式
继承的语法格式为:
class <子类名>(父类名1,父类名2,…,父类名n):
类体
如果在父类命中没有定义任何对象,那么父类默认为是Object,Object是所有子类的父类,里面定义了所有类共有实现功能,比如__new__.在子类中继承父类的方法为<父类名>.init(参数列表),比如下面的代码中的
Person.init(self,name,age)就继承了Person类中的实例方法,即Student类也可以使用Person中的方法。
class Person():
def __init__(self,name,age):
self.age=age
self.name=name
def printage(self):
print('{}的年龄为:{}岁'.format(self.name,self.age))
class Student(Person):
def __init__(self,name,age,score):
self.score=score
Person.__init__(self,name,age)
def printscore(self):
print('{}的年龄为{},分数为{}'.format(self.name,self.age,self.score))
Person1=Person('张三',18)
Person1.printage()
Student1=Student('张三',18,100)
Student1.printage()
Student1.printscore()
输出结果:
张三的年龄为:18岁
张三的年龄为:18岁
张三的年龄为18,分数为100
2.2 类成员的继承与重写
类成员可以继承或重写父类中的属性,在上面的代码基础上对printage语句进行重写
def printage(self):
print(‘报告老师,{}的年龄为:{}岁!’.format(self.name, self.age)),示例代码如下:
class Person():
def __init__(self,name,age):
self.age=age
self.name=name
def printage(self):
print('{}的年龄为:{}岁'.format(self.name,self.age))
class Student(Person):
def __init__(self,name,age,score):
self.score=score
Person.__init__(self,name,age)
def printscore(self):
print('{}的年龄为{},分数为{}'.format(self.name,self.age,self.score))
def printage(self):
print('报告老师,{}的年龄为:{}岁!'.format(self.name, self.age))
Person1=Person('张三',18)
Person1.printage()
Student1=Student('张三',18,100)
Student1.printage()
Student1.printscore()
输出结果:
张三的年龄为:18岁
报告老师,张三的年龄为:18岁!
张三的年龄为18,分数为100
2.3 查看类的层次结构
通过<类名.mro()>可以查看类的层次结构,如下代码所示:
class A():pass
class B(A):pass
class C(B):pass
print(C.mro())
输出结果:
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
2.4 dir()查看对象的属性
object为所有类对象的父类,通多di()函数查看对象的属性比较object与其他类对象属性的差别,示例代码如下:
显然,Car类包含了object所有的属性,即Car为Object的子类。
class Car():
def __init__(self,price,brand):
self.price=price
self.brand=brand
def output(self):
print('这辆车的品牌是{},价格是{}'.format(self.price,self.brand))
print(dir(Car))
print(dir(object))
输出结果:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'output']
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
2.5 重写__str__方法
object类中有一个__str__方法,其作用是将对象转化为一个字符串,示例代码如下:
class Car():
def __init__(self,price,brand):
self.price=price
self.brand=brand
def __str__(self):
return '这辆车的品牌是{},价格是{}'.format(self.brand,self.price,)
Car1=Car(500000,'大众')
print(Car1)
输出结果:
这辆车的品牌是大众,价格是500000
2.6 多重继承
python中一个子类可以继承多个父类,形式为class C(B,A) A,B为父类,实例代码如下:
class A():
def a(self):
print('a')
class B():
def b(self):
print('b')
class C(B,A):
def c(self):
print('c')
C1=C()
C1.a()
C1.b()
C1.c()
输出结果:
a
b
c
python支持多重继承,子类继承的父类中有相同的方法名的时候,系统会根据类的层次结构从左往右调用:
class A:
def aa(self):
print("aa")
def say(self):
print("say AAA!")
class B:
def bb(self):
print("bb")
def say(self):
print("say BBB!")
class C(B,A):
def cc(self):
print("cc")
c = C()
print(C.mro()) #打印类的层次结构
c.say()
输出结果:
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
say BBB!
3 多态
多态是指同一个方法调用由于对象不同产生的行为也不同,需要注意的两点:
- 多态指的是方法的多态,属性没有多态;
- 多态存在的必要条件是方法重写与继承。
class China(country):
def Nationalflag(self):
print('中国的国旗是五星红旗!')
class America(country):
def Nationalflag(self):
print('美国的国旗是米字旗!')
class India(country):
def Nationalflag(self):
print('印度的国旗是条纹型旗!')
def Nationalflagout(a):
if isinstance(a,country):
a.Nationalflag()
Nationalflagout(China())
Nationalflagout(America())
Nationalflagout(India())
输出结果:
中国的国旗是五星红旗!
美国的国旗是米字旗!
印度的国旗是条纹型旗!
4 组合
类可以通过组合将两个类的功能拼接在一起,形成一个新的类(拥有两个类的功能)。
class A():
def a(self):
print('输出a')
class B():
def b(self):
print('输出b')
class AB():
def __init__(self,A,B):
self.A=A
self.B=B
a=A()
b=B()
ab=AB(a,b)
ab.A.a()
ab.B.b()
输出结果:
输出a
输出b
5 设计模式—工厂模式
工厂模式即实现了创建者和调用者的分离,使得代码写作效率更高。
class Carfactory():
def creatcar(self,brand):
if brand=='奔驰':
return Benz()
elif brand=='宝马':
return BMW()
elif brand=='比亚迪':
return BYD()
else:
print('抱歉,没有该品牌的汽车')
class Benz():
def benz(self):
print( '恭喜您获得奔驰汽车!')
class BMW():
def bmw(self):
print('恭喜您获得宝马汽车!')
class BYD():
def byd(self):
print('恭喜您获得比亚迪汽车')
factory=Carfactory()
Car1=factory.creatcar('奔驰')
Car2=factory.creatcar('宝马')
Car3=factory.creatcar('比亚迪')
Car4=factory.creatcar('奥迪')
print(Car1)
print(Car2)
print(Car3)
print(Car4)
输出结果:
抱歉,没有该品牌的汽车
<__main__.Benz object at 0x0000021708E6AC08>
<__main__.BMW object at 0x0000021708E6AC48>
<__main__.BYD object at 0x0000021708E6AC88>
None
6 设计模式—单例模式
单例模式的核心是确保一个类只有一个实例,闭关且提供一个访问该实例的访问点。
单例模式只生成一个实例对象,对于要打开较大的文档会消耗大量的内存与资源,这时如果使用单例模式使得类程序只能执行一次,那么会极大减小内存的占用。
从代码中输出结果可以看出,虽然输入了两个实例属性,但是实际上只执行了一次,以下代码可以直接套用在其他类代码中使得(稍加更改即可)该类函数始终只能执行一次。
class Student():
__a=None
__b=True
def __new__(cls, *args, **kwargs):
if cls.__a == None:
cls.__a = object.__new__(cls)
return cls.__a
def __init__(self,name,age,score):
if Student.__b:
print('执行我啦')
self.name=name
self.age=age
self.score=score
Student.__b=False
S1=Student('张三',18,100)
print(S1)
S2=Student('李四',20,90)
print(S2)
输出结果:
执行我啦
<__main__.Student object at 0x000001F3C5FB1948>
<__main__.Student object at 0x000001F3C5FB1948>