文章目录
1.方法的动态性
python中的方法不能重名,定义了多个重名都只有最后一个有效
python是动态语言,可以动态增加方法
class Person:
def work(self):
print('work')
def play_game(s):
print('{0}paly'.format(s))
def work2(s):
print('好好学习')
Person.play = play_game # 将play_game这个方法赋给Persen.play
Person.work2 = work2 # 将work2这个方法赋给work2
p = Person()
p.work()
p.play() #Person.play(p),所以这里是不用给参数的
p.work2()
2.私有属性和方法
方法本质和属性一样,都是对象
class Employee:
__company = 'swjtu' #私有类属性
def __init__(self,name,age):
self.name = name
self.__age = age #私有属性
def __work(self): #私有方法
print('work hard')
print('内部调私有属性,年龄{0}'.format(self.__age))
e = Employee('selene',18)
print(e.name)
print(e._Employee__age) #私有属性外部访问
e._Employee__work() #私有方法外部访问
print(Employee._Employee__company) #私有类属性外部访问
3. @property装饰器
@property装饰器将一个方法的调用变成一个属性的调用
使用:
class Employee:
@property
def salary(self):
print('salary run...')
return 100
emp1 = Employee()
print(emp1.salary)#作为属性的调用,不能赋值
#emp1.salary = 1000会报错
4.练习:私有属性和@property完成控制工资录入
两端代码效果一样
#用私有属性控制薪水录入错误
class Employee2:
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('录入错误')
emp2 = Employee2('selene',30000)
print(emp2.get_salary())
emp2.set_salary(2000)
print(emp2.get_salary())
#@property
class Employee3:
def __init__(self, name, salary):
self.name = name
self.__salary = salary #属性私有
@property
def salary(self): #用这个方法给私有属性赋值,相当于get_salary方法
return self.__salary
@salary.setter #针对salar属性的设置,相当于set_salary方法
def salary(self,salary):
if 2000<salary<50000:
self.__salary = salary
else:
print('录入错误')
emp3 = Employee3('selene',40000)
print(emp3.salary)
emp3.salary = 10000 #这里可以赋值成功!!!!!!!
print(emp3.salary)
5.面向对象的三大特征
6.继承
(1)继承
class Person:
def __init__(self,name,age):
self.name = name
self.__age = age #父类私有属性,子类继承了但不能直接用
def say_age(self):
print('jiecheng')
class Student(Person):
def __init__(self,name,age,score):
Person.__init__(self,name,age) #直接写self.name = name也行,这里是显示调用
self.score = score
print('Student的继承关系',Student.mro()) #查看Student的继承关系
s = Student('selene',18,100)
s.say_age() #继承了父类的方法
print(dir(s)) #查看s的所有属性
print('父类非私有属性:',s.name)
print('父类私有属性:',s._Person__age) #父类的私有属性需要这样调用,不能直接使用
'''
Student的继承关系 [<class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>]
jiecheng
['_Person__age', '__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__', 'name', 'say_age', 'score']
父类非私有属性: selene
父类私有属性: 18
'''
(2)方法重写
子类继承了父类,可以重新定义父类的方法,叫方法重写
class Person:
def __init__(self,name,age):
self.name = name
self.__age = age
def say_age(self):
print('print my age:',self.__age)
def say_name(self):
print('print my name:', self.name)
class Student(Person):
def __init__(self,name,age,score):
Person.__init__(self,name,age) #直接写self.name = name也行,这里是显示调用
self.score = score
def say_name(self):
print('我的名字是:',self.name)
def say_age(self):
print('我的年龄是:',self._Person__age)#name是父类的私有属性
s = Student('selene',18,100)
s.say_name()
s.say_age()
'''
我的名字是: selene
我的年龄是: 18
'''
(3)object根类
class_name.mor()
object类是其他所有类的父类
(4)重写_str_方法
#重写object的_str_()
class Person:
def __init__(self,name):
self.name = name
def __str__(self):
return '名字是:{0}'.format(self.name)
p = Person('selene')
print(p)
'''
没有_str_时的结果:
<__main__.Person object at 0x000002096990DB08>
有_str_时的结果:
名字是:selene
'''
(5)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()
'''结果:
A: <__main__.B object at 0x00000272A8B11108>
B: <__main__.B object at 0x00000272A8B11108>
'''
7.多态
class Man:
def dinner(self):
print('吃饭')
class Chinese(Man):
def dinner(self):
print('筷子')
class English(Man):
def dinner(self):
print('叉子')
def manEat(m):#形参m需要传一个类
if isinstance(m,Man):#isinstance()判断对象是否是一个一已知的类型,如isintance(2,int),返回true,且考虑继承
m.dinner()
else:
print('no dinner')
#同一方法调用,由于对象不同可能产生不同的行为
manEat(Chinese())
manEat(English())
'''结果
筷子
叉子
'''
8. 特殊方法和运算符重载
#重载运算符
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:
print('不是同类对象,不能相加')
def __mul__(self,other):#重写乘法
if isinstance(other,int):
return self.name*other
else:
return '不是整数倍,不能相乘'
p1 = Person('bai')
p2 = Person('selene')
x = p1 + p2
y = p1*3
print(x,y)
'''结果
bai--selene baibaibai
'''
9.特殊属性
class A:
def aa(self):
print('AA')
class B:
def bb(self):
print('BB')
class C(A,B):
def __init__(self,name):
self.name = name
def cc(self):
print('cc')
c = C('selene')
print('获得c的所有属性',dir(c))
print('获得c添加的属性',c.__dict__)
print('获得c的类',c.__class__)
print('获得C的父类(多个)',C.__bases__)
print('获得C的类层次结构',C.mro())
'''结果
获得c的所有属性 ['__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__', 'aa', 'bb', 'cc', 'name']
获得c添加的属性 {'name': 'selene'}
获得c的类 <class '__main__.C'>
获得C的父类(多个) (<class '__main__.A'>, <class '__main__.B'>)
获得c的类 [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
'''
10. 组合
#使用继承
class A1:
def say_a1(self):
print('a1a1')
class B1(A1):
pass
b1 = B1()
b1.say_a1()
#使用组合
class A2:
def say_a2(self):
print('a2a2')
class B2:
def __init__(self,a):
self.a = a
a2 = A2()
b2 = B2(a2)
b2.a.say_a2()
'''结果
a1a1
a2a2
'''
11.设计模式
(1)工厂模式
class CarFactory:
def create_car(self,brand):
if brand == 'Benz':
return Benz()
elif brand =='BMW':
return BMW()
elif brand =='BYD':
return BYD()
else:
return 'unknown brand'
class Benz:
pass
class BMW:
pass
class BYD:
pass
factory = CarFactory()
c1 = factory.create_car('BMW')
print(c1)
(2)单例模式
确保一个类就只有一个对象
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)
'''结果
init...
<__main__.MySingleton object at 0x00000182E01F1588>
<__main__.MySingleton object at 0x00000182E01F1588>
'''
#工厂模式和单例模式的整合
class CarFactory:
_obj = None
__init_flag = True
def create_car(self,brand):
if brand == 'Benz':
return Benz()
elif brand =='BMW':
return BMW()
elif brand =='BYD':
return BYD()
else:
return 'unknown brand'
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('BMW')
c2 = factory.create_car('BYD')
print(c1)
print(c2)
factory2 = CarFactory()
print(factory)
print(factory2)
'''结果
<__main__.BMW object at 0x00000232A81D1C88>
<__main__.BYD object at 0x00000232A81D1C48>
<__main__.CarFactory object at 0x00000232A81D1C08>
<__main__.CarFactory object at 0x00000232A81D1C08>
'''