目录
方法没有重载
方法签名:方法名,参数数量,参数类型
python中方法参数没有数据类型,参数数量也可由可变参数控制,因此,python中没有方法重载。若定义多个重名方法,只有最后一个方法有效,前面的方法被覆盖了
方法的动态性
class Person():
def work(self):
print('努力上班!')
def play_game(a):
print('{0}在玩游戏'.format(a))
def work2(self):
print('好好工作,努力上班!挣大钱.')
Person.play = play_game
p = Person()
p.work()
p.play()
Person.work = work2
p.work()
私有属性和私有方法(实现封装)
私有属性
要点:
1.两个下划线开头的属性为私有属性,其余为共有属性
2.类的内部可以访问私有属性
3.类的外部不可以直接访问私有属性
4.类的外部可以通过“__类名__私有属性名(方法名)”访问私有属性
注:方法本质上也是属性
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.age)
print(e._Employee__age)
print(dir(e))
e._Employee__work()
print(e._Employee__company)
@property 装饰器
@property可以将一个方法的调用方式变成“属性调用”。增加getter和setter
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<50000:
self.__salary = salary
else:
print('录入错误!薪水在1000-50000之间')
emp1 = Employee('刘美丽', 30000)
print(emp1.salary)
emp1.salary = -20000
print(emp1.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(-20000)
#print(emp1.get_salary())
"""
面向对象的三个特征
-
封装
隐藏对象的属性和实现细节,只对外提供必要的方法。使用 “私有属性,私有方法” 的方式实现封装。 -
继承
让子类具有父类的特性,且在父类设计不变的情况下,可以增加子类的功能或者改进已有的算法。 -
多态
同一种方法调用时,不同的对象产生不同的行为
继承
已有的类,称为 ”父类“ 或者 ”基类“,新类称为 ”子类“ 或者 ”派生类“。
语法:
class 子类名称(父类1[,父类2,…]):
类体
object是所有类的父类,类定义中没有指定父类时,默认父类时object类
定义子类时,必须在其构造函数中调用父类的构造函数。
语法:
父类名.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
# Student-->Person-->object类
print(Student.mro())
s = Student('刘美丽',19,100)
s.say_age()
print(s.name)
#print(s.age)
print(dir(s))
print(s._Person__age)
类成员的继承和重写
1.成员继承:子类继承了父类处构造器之外的所有成员
2.方法重写:子类可以重新定义父类中的方法,这样会覆盖父类中的方法,也称为 “重写”。
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()
查看类的继承层次结构
通过类的方法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))
s2 = Person('刘美丽',18)
print(dir(s2))
重写__str__()方法
用于返回对于一个对象的描述
class Person: #默认继承object
def __init__(self,name):
self.name = name
def __str__(self):
return '名字是{0}'.format(self.name)
p = Person('刘美丽')
print(p)
多重继承
一个子类可以有多个 “直接父类”,但会使得 “类的整体层次”搞得异常复杂,因此应该尽量避免使用。
class A:
def aa(self):
print('aa')
def say(self):
print('say AAA!')
class B:
def bb(self):
print('bb')
def say(self):
print('my BBB!')
class C(B,A):
def cc(self):
print('cc')
c = C()
c.cc()
c.bb()
c.aa()
print(C.mro())
c.say
super()获得父类的定义
class A:
def say(self):
print('A:',self)
class B:
def say(self):
#A.say(self)
super().say() #获得父类的定义对象
print('B:',self)
B().say()
多态
同一方法调用时,由于对象的不同可能会产生不同的结果。
要点:
- 多态是方法的多态,属性没有多态
- 多态存在有两个必要的条件:继承和方法重写
class Man:
def eat(self):
print('饿了,吃饭啦!')
class Chinese(Man):
def eat(self):
print('中国人用筷子吃饭')
class English(Man):
def eat(self):
print('英国人用叉子吃饭')
class Indian(Man):
def eat(self):
print('印度人用手吃饭')
def manEat(m):
if isinstance(m,Man):
m.eat() #多态,一个方法调用,根据不同的方法调用不同的对象
else:
print('不能吃饭')
manEat(Chinese())
manEat(Indian())
特殊方法和运算符重载
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 '不是同类对象,不能相加'
def __mul__(self, other):
if isinstance(other,int):
return self.name*other
else:
return '不是同类对象,不能相加'
p1 = Person('真漂亮')
p2 = Person('刘美丽')
p3 = 4
x = p1 + p2
print(x)
y = p1 * p3
print(y)
特殊属性
class A:
def aa(self):
print('bb')
def say(self):
print('say AA!')
class B:
def bb(self):
print('bb')
def say(self):
print('say BB!')
class C(B,A):
def __init__(self,nn):
self.nn = nn
def cc(self):
print('cc')
c = C(3)
print(C.mro()) #打印类的层次结构
c.say() #解释器寻找方法按“从左到右”的方式寻找,此时会执行B中的say()
print(dir(c))
print(c.__dict__)
print(c.__class__)
print(C.__bases__)
print(A.__subclasses__())
对象的浅拷贝和深拷贝
浅拷贝只拷贝本身的值,补考呗子对象的内容,深拷贝除了拷贝对象本身,也拷贝对象的所有子对象。
import copy
class MobilePhone:
def __init__(self,CPU,screen):
self.CPU = CPU
self.screen = screen
class CPU:
def caculate(self):
print('我是快乐的CPU')
print('CPU对象:',self)
class Screen:
def show(self):
print('显示一幅美丽的话')
print('screen对象:', self)
#测试变量赋值
c1 = CPU()
c2 = c1
print(c1)
print(c2)
#测试浅复制
print('--------测试浅复制---------')
s1 = Screen()
m1 = MobilePhone(c1,s1)
m2 = copy.copy(m1)
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)
组合
实现一个类拥有另一个类的方法和属性.
#使用继承实现代码的复用
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()
class MobilePhone:
def __init__(self,cpu,screen):
self.cpu = cpu
self.screen = screen
class CPU:
def calculate(self):
print('我是快乐的CPU')
print('CPU对象:',self)
class Screen:
def show(self):
print('显示一幅美丽的话')
print('screen对象:', self)
m = MobilePhone(CPU(),Screen())
m.cpu.calculate()
m.screen.show()
设计模式——工厂模式实现
工厂模式
帮助构造对象,实现创建者和调用者的分离
class CarFactory:
def creat_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.creat_car('奔驰')
c2 = factory.creat_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)
工厂模式和单例模式的使用整合
class CarFactory:
__obj = None # 类属性
__init_flag = True
def creat_car(self,brand):
if brand == '奔驰':
return Benz()
elif brand == '宝马':
return BMW()
elif brand == '比亚迪':
return BYD()
else:
return '未知品牌,无法创建'
__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):
if CarFactory.__init_flag:
print('init CarFactory...')
CarFactory.__init_flag = False
class Benz:
pass
class BMW:
pass
class BYD:
pass
factory = CarFactory()
c1 = factory.creat_car('奔驰')
c2 = factory.creat_car('比亚迪')
print(c1)
print(c2)
factory2 = CarFactory()
print(factory)
print(factory2)