总览
多态
什么是多态?
多态在python中的应用
鸭子类型
封装
广义的封装
狭义的封装
私有化
原理
使用方式 使用场景
复习 正常类 改装成 抽象类
正常类
class Person: def func1(self): pass
抽象类
from abc import ABCMeta,abstractmethod#第一步 class Person(metaclass= ABCMeta):#第二步 元类 @abstractmethod#第三部 装饰器 def func1(self): pass @abstractmethod def func2(self):#第三部 pass
class Student: def __init__(self): self.name = 'alex' def name(self): print(123) alex = Student() print(alex.name())#相当于'alex'() 肯定无法执行
str' object is not callable
Student.name((0))#通过类名可以调用到这个方法
123
class A: def func(self): pass a = A() print(a.func)#方法 print(A.func)#函数
<bound method A.func of <__main__.A object at 0x0000000671EF8B70>> <function A.func at 0x00000006720967B8>
函数与方法的区别
class A: def func(self): pass a = A() from types import MethodType,FunctionType print(isinstance(a.func,MethodType)) print(isinstance(a.func,FunctionType))
True False
self指的是什么?
self指的是对象的本身
class Foo: def func(self): print('foo.func') obj =Foo f = obj.func print(f) print(obj.func)
class Base1: def f1(self): print('base1,f1') def f2(self): print('base1,f2') def f3(self): print('base1,f3') self.f1 class Baes2: def f1(self): print('base2.f1') class Foo(Base1,Baes2): def f0(self): print('foo.f0') self.f3() obj = Foo() obj.f0()
练习1
class Person: def __init__(self,name,pwd,email): self.name = name self.pwd = pwd self.email = email user_list = [] i = 0 while 1: if i >= 3 :break i += 1 user = input('请输入用户名:') pwd = input('请输入密码:') email = input('请输入邮箱:') obj = Person(user,pwd,email) user_list.append(obj) for i in user_list: print('我叫:{},我的邮箱是:{}'.format(i.name,i.email))
练习2
class User: def __init__(self,name,pwd): self.name = name self.pwd = pwd class Account: def __init__(self): self.user_list = [] def login(self): username = input("请输入用户名:") password = input('请输密码:') for i in self.user_list: if username == i.name and password == i.pwd: return True def register(self): username = input("请输入用户名:") password = input('请输密码:') usr = User(username,password) self.user_list.append(usr) def run(self): for i in range(2): self.register() for i in range(3): if self.login():break#这个break 是打断for循环 else: print('登录失败!!') a = Account() a.run()
正式开始类的封装
记住一句真理:在python中一切皆对象!!!
str是一个基本数据类型,
str是一个类
a = 'abc'#a是一个对象,默认的调用str()类来实例化对象,
b = str(123)#type(b) 就是类的名字
str是一个类,str()就是实例化一个对象,
class Person:pass obj = Person() print(type(obj))
<class '__main__.Person'>#打印的就是类的名字
在java语言中,使用多态来解决传参的时候,数据类型规范的问题
在java语言中,函数定义的时候一定要,在形参的前面定义参数的类型
class Applepay: def pay(self):pass class Alipay: def pay(self):pass def pay(Applepay obj,int money): obj.pay
#或者
def pay(Alipay obj,int money): obj.pay
问题如何解决??
一个父类被多个子类继承。。
class Payment:pass class Applepay(Payment): def pay(self):pass class Alipay(Payment): def pay(self):pass def pay(Payment obj,int money): obj.pay
#或者
def pay(Payment obj,int money): obj.pay
什么是鸭子类型???
长得像鸭子,走起路来像鸭子,那么这就是鸭子
len()#str list tuple dict set range()都可以使用
但是len()函数并没有规范他的数据类型
class lentype:pass class str(lentype):pass class list(lentype):pass class tuple(lentype):pass class dict(lentype):pass class set(lentype):pass
不是明确的通过继承实现多态
封装
广义的封装
class 类名: def 方法1(self):pass
定义了一个类,只有这个类的对象才能够使用定义在类的方法
狭义的封装
类中的私有成员
私有的静态属性
私有的对象的属性
私有的方法
为什么要定义一个私有的变量
不想别人看见 类中的某一个值
不想让别人 类中的某一个值
修改类中的某一个值 满足一定的条件,在一定范围里面修改
正常的定义一个类
class Goods: discount = 0 print(Goods.discount)
0
隐藏类中的属性
静态属性的私有化
class Goods: __discount = 0#在静态属性的的前面加上两个下划线 print(Goods.__discount)
type object 'Goods' has no attribute '__discount#Goods没有赋值__discount
所以在类的外部无法访问类的私有属性
class Goods: __discount = 0 print(Goods.__discount)
直接飘红,类中的代码执行加载完成之前,类的名字不会出现在内存之中,也就是类的名字是最后才生成的
类中的静态属性,变量的名字,在程序加载的过程中就已经执行完毕
class Goods: __discount = 0 print(__discount)#0
私有的静态属性可以再类的内部使用
class Goods(): __discount = 0 #变形--> _类名__变量名 print(Goods.__dict__)
{'__module__': '__main__', '_Goods__discount': 0, '__dict__': <attribute '__dict__' of 'Goods' objects>, '__weakref__': <attribute '__weakref__' of 'Goods' objects>, '__doc__': None}
变形之后在外面如何访问??
class Goods(): __discount = 0 print(Goods._Goods__discount)#0
所以还是可以访问的
通过在类中建立一个函数来访问类的私有属性
class Student: def __init__(self,name,age): self.__name = name #__name私有化类的静态属性 self.age = age def name(self):#建立一个函数来访问类的私有属性 return self.__name taibai = Student('taibai',20) print(taibai.name()) print(taibai.age) taibai.age = 'abc'#重新赋值 print(taibai.age)
taibai 20 abc
再举一个例子
class Goods: __discount = 0.7 #私有打折的值 def __init__(self,name,price): self.name = name self.__prioce = price #私有商品的价格 def price(self): return self.__prioce*self.__discount apple = Goods('苹果',10) print(apple.price())
7.0
如何实现用户注册的时候 给用户密码加密
class User: def __init__(self,username,password): self.name = username self.__pwd = password self.pwd = self.__getpwd()#返回的可以访问的密码是加密之后密码 def __getpwd(self):#类中建立一个加密函数,这个函数(方法)也是私有的 return hash(self.__pwd) obj = User('Alex','abc12') print(obj.name) print(obj.pwd)
Alex -6259944086391752847
修改类中的某一个值 (满足一定的条件,在一定范围里面)修改
class Goods: __discount = 0.7 def __init__(self,name,price): self.name = name self.__price = price def price(self): return self.__price * Goods.__discount#返回的是商品打折之后的价格 def change_price(self,new_price): if type(new_price) is int: self.__price = new_price apple = Goods('name',5) print(apple.price()) apple.change_price(10) print(apple.price())
3.5 7.0
私有变量能否在外面被定义
class A: __country = 'China' print(A.__dict__)#'_A__country': 'China', A.__language = 'Chinese' print(A.__dict__)#'_A__country': 'China','__language': 'Chinese'
如何实现类的方法或属性不被子类继承???
class A: __country = 'China' def __init__(self,name): self.__name = name # _A__name class B(A): # print(__country)#name '_B__country' is not defined def get_name(self): return self.__name b = B('alex') print(b.__dict__)
{'_A__name': 'alex'}
内置函数
property
name是对象的一私密属性 但是需要访问你的时候 需要用函数name()
可不可以直接 对象名.name 就能访问??
class Student: def __init__(self,name,age): self.__name = name self.age = age @property def name(self): return self.__name taibai = Student('taibai',18) print(taibai.name)
taibai
访问圆的周长和面积
from math import pi class Cicle: def __init__(self,r): self.r = r @property def area(self): return pi * self.r**2 @property def perimeter(self): return 2*pi*self.r c1 = Cicle(10) print(c1.area) print(c1.perimeter)#注意哦这里已经不需要加括号了!!
314.1592653589793 62.83185307179586