1.方法没有重载
如果我们在类体中定义了多个重名的方法,只有最后一个方法有效
2.方法的动态性
动态的为类添加新的方法,或者动态的修改类已有的方法
class Person:
def work(self):
print("努力上班!")
def play_game(s):
print('{0}在玩游戏'.format(s))
def work2(s):
print("好好工作,努力上班!赚大钱,娶媳妇")
p=Person()
Person.work=work2
p.work()
好好工作,努力上班!赚大钱,娶媳妇
3.私有属性和私有方法(实现封装)
两个下划线开头的属性是私有的(private),其他是公共的(public)
类内部可以访问私有属性(方法)
类外部不能直接访问私有属性(方法)
类外部可以通过“类名 _私有属性(方法)名”访问私有属性(方法)
class Employee:
__company='百战程序员'
def __init__(self,name,age):
self.name=name ##公有属性
self.__age=age ##私有属性
def __work(self): ##私有方法
print("好好工作,赚钱娶媳妇!")
print("年龄:{0}".format(self.__age))
print(Employee.__company)
e=Employee("高琪",18)
print(e.name)
print(e._Employee__age)
e._Employee__work()
print(Employee._Employee__company)
好好工作,赚钱娶媳妇!
年龄:18
百战程序员
百战程序员
4.@property装饰器 代替_get和_set方法
@property可以将一个方法的调用方式变成“属性调用”。
不用@property
class Employee:
def __init__(self,name,salary):
self.__name=name
self.__salary=salary
def get_salary(self):
return self.__salary
def set_salary(self,salary):
if 1000<salary<50000:
self.__salary=salary
else:
print("录入错误!薪水在1000-50000范围")
emp1=Employee('高琪',30000)
print(emp1.get_salary())
emp1.set_salary(2000)
print(emp1.get_salary())
30000
2000
用@property
class Employee:
def __init__(self,name,salary):
self.__name = name
self.__salary = salary
@property
def salary(self):
return self.__salary
@salary.setter
def salary(self, salary):
if 1000<salary<5000:
self.__salary=salary
else:
print("录入错误!薪水在1000-50000范围")
emp1 = Employee('高琪',30000)
print(emp1.salary)
emp1.salary=20
print(emp1.salary)
30000
录入错误!薪水在1000-50000范围
30000
5.面向对象三大特征(封装、继承、多态)
继承:一个子类可以继承多个直接的父类
语法格式
class 子类类名(父类1[,父类2……]):
类体
如果没有指定父类,默认父类是object类
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
s=Student('高琪',18,60)
s.say_age()
print(s.name)
print(s._Person__age)
高琪
18
类成员的继承和重写
成员继承:子类继承了父类除构造器之外的所有成员
方法重写:子类可以重新定义父类中的方法,这样就会覆盖父类的方法,称为重写
class Person:
def __init__(self,name,age):
self.name=name
self.__age=age ##私有属性
def say_age(self):
print("我的年龄:",self.__age)
def say_introduce(self):
print("我的名字是{0}".format(self.name))
class Student(Person):
def __init__(self,name,age,score):
Person.__init__(self,name,age) ##必须显示调用父类的方法,不然解释器不会调用
self.score=score
def say_introduce(self):
##重写父类的方法
print("报告老师,我的名字是:{0}".format(self.name))
s=Student('高琪',18,80)
s.say_age()
s.say_introduce()
我的年龄: 18
报告老师,我的名字是:高琪
6.object()根类
通过类的方法mro()或者类的属性__mro()__可以输出这个类的继承层次结构。
7.重写__str()__方法
用于返回一个对于“对象是描述”,对应于内置函数str(),经常用于print()方法,帮助我们查看对象的信息。__str()__可以重写。
class Person: ##继承object()
def __init__(self,name):
self.name=name
def __str__(self):
return "名字是{0}".format(self.name)
p=Person('高琪')
print(p)
名字是高琪
8.多重继承
一个子类可以有多个直接父类,具备了多个父类的特点。但是会被“类的整体层次”搞得异常复杂,尽量避免使用
9.mro()
如果父类中有相同名字的方法,在子类没有指定父类名时,解释器将“从左向右”按顺序搜索
10.super()获得父类的定义
super()代表父类的定义,不是父类的对象
class A:
def say(self):
print('A:',self)
class B(A):
def say(self):
#A.say(self)
super().say()
print("B:",self)
B().say()
11.多态
同一个方法调用由于对象不同可能会产生不同的行为
1.多态是方法的多态,属性没有多态
2.多态的存在有两个必要条件 继承、方法重写
class Man:
def eat(self):
print('饿了,吃饭拉!')
class Chinese(Man):
def eat(self):
print('中国人用筷子吃饭')
class English(Man):
def eat(self):
print("英国人用叉子吃饭")
class India(Man):
def eat(self):
print('印度人用右手吃饭')
def manEat(m):
if isinstance(m,Man):
m.eat() #多态,一个方法调用,根据对象不同调用不同的方法
else:
print('不能吃饭')
manEat(Chinese())
中国人用筷子吃饭
12.特殊方法和运算符重载
见笔记
我们可以重写上面的特殊方法,即实现了“运算符的重载”
class Person:
def __init__(self,name):
self.name=name
def __add__(self,other):
if isinstance(other,Person):
return'{0}--{1}'.format(self.name,other.name)
else:
return '不是同类对象,不能相加'
p1=Person("高琪")
p2=Person('高希希')
x=p1+p2
print(x)
高琪–高希希
13.特殊属性
Python对象中包含了很多双下划线开始和结束的属性,这些是特殊属性,有特殊用法。
14.对象的浅拷贝和深拷贝
浅拷贝
拷贝时,对象包含的子对象内容不拷贝。因此,源对象和拷贝对象会引用同一个子对象
深拷贝
递归拷贝对象中包含的子对象。源对象和拷贝对象所有的子对象也不同。
##浅拷贝和深拷贝
import copy
class MobilePhone:
def __init__(self,cpu,screen):
self.cpu=cpu
self.screen=screen
class CPU:
def calculate(self):
print('算你个12345')
print('cpu对象:',self)
class Screen:
def show(self):
print('显示一个好看的画面,亮瞎你的钛合金大眼')
print('screen对象:',self)
##测试浅拷贝
s1=Screen()
c1=CPU()
m1=MobilePhone(c1,s1)
m2=copy.copy(m1)
print('测试浅拷贝')
print(m1,m1.cpu,m1.screen)
print(m2,m2.cpu,m2.screen)
##测试深拷贝
print('测试深拷贝')
m3=copy.deepcopy(m1)
print(m1,m1.cpu,m1.screen)
print(m3,m3.cpu,m3.screen)
测试浅拷贝
<main.MobilePhone object at 0x0000024CDB24FEC8> <main.CPU object at 0x0000024CDB24FD88> <main.Screen object at 0x0000024CDB24FE88>
<main.MobilePhone object at 0x0000024CDB24FF08> <main.CPU object at 0x0000024CDB24FD88> <main.Screen object at 0x0000024CDB24FE88>
测试深拷贝
<main.MobilePhone object at 0x0000024CDB24FEC8> <main.CPU object at 0x0000024CDB24FD88> <main.Screen object at 0x0000024CDB24FE88>
<main.MobilePhone object at 0x0000024CDB24FF88> <main.CPU object at 0x0000024CDB230048> <main.Screen object at 0x0000024CDB2300C8>
15.组合
‘is-a’关系,我们可以使用继承,从而实现子类拥有父类的方法和属性。
‘has-a’关系,我们可以使用组合,也能实现一个类拥有另一个类的方法和属性。
##测试组合
class A1:
def say_a1(self):
print('a1,a1,a1')
class B1(A1): #继承代码的复用
pass
b1=B1()
b1.say_a1()
class A2:
def say_a2(self):
print('a2,a2,a2')
class B2: ##同样的效果,用组合实现代码的复用
def __init__(self,a):
self.a=a
a2=A2()
b2=B2(a2)
b2.a.say_a2()
a1,a1,a1
a2,a2,a2
15.设计模式_工厂模式实现
设计模式是面向对象语言特有的内容,是我们面临某一类问题时固定的做法
工厂模式实现了创建者和调用者的分离,使用专门的工厂类将选择实现类、创建对象进行统一的管理和控制
工厂模式
class CarFactory:
def create_car(self,brand):
if brand=="奔驰":
return Benz()
elif brand=="宝马":
return BMW()
elif brand=='比亚迪':
return BYD()
else:
return '未知品牌,无法创建'
class Benz:
pass
class BMW:
pass
class BYD:
pass
factory=CarFactory()
c1=factory.create_car('奔驰')
c2=factory.create_car('比亚迪')
print(c1)
print(c2)
单例模式
单例模式的核心作用是确保一个类只有一个实例,并且提供一个访问该实例的全局访问点。
单例模式只生成一个实例对象,减少了对系统资源的开销。当一个对象的产生需要比较多的资源,如读取配置文件、产生其他依赖对象时,可以产生一个‘单例对象’,然后永久驻留内存中,从而极大的降低开销。
class MySingleton:
__obj=None #创建的类用一个属性来保存起来 类属性
__init_flag=True
def __new__(cls, *args, **kwargs):
if cls.__obj==None:
cls.__obj=object.__new__(cls)
return cls.__obj
def __init__(self,name):
if MySingleton.__init_flag:
print("init.....")
self.name=name
MySingleton.__init_flag=False
a=MySingleton('aa')
b=MySingleton('bb')
print(a)
print(b)
c=MySingleton('cc')
print(c)
init…
<main.MySingleton object at 0x000001890EE7C088>
<main.MySingleton object at 0x000001890EE7C088>
<main.MySingleton object at 0x000001890EE7C088>
工厂模式和单例模式的整合使用
class CarFactory:
__obj = None # 创建的类用一个属性来保存起来 类属性
__init_flag = True
def create_car(self,brand):
if brand=="奔驰":
return Benz()
elif brand=="宝马":
return BMW()
elif brand=='比亚迪':
return BYD()
else:
return '未知品牌,无法创建'
def __new__(cls, *args, **kwargs):
if cls.__obj==None:
cls.__obj=object.__new__(cls)
return cls.__obj
def __init__(self):
if CarFactory.__init_flag:
print("init.....")
CarFactory.__init_flag=False
class Benz:
pass
class BMW:
pass
class BYD:
pass
factory=CarFactory()
c1=factory.create_car('奔驰')
c2=factory.create_car('比亚迪')
print(c1)
print(c2)
factory2=CarFactory()
print(factory2)
print(factory)
init…
<main.Benz object at 0x00000195B134A2C8>
<main.BYD object at 0x00000195B134A348>
<main.CarFactory object at 0x00000195B134A488>
<main.CarFactory object at 0x00000195B134A488>