day19 多态 多态在python中的应用 鸭子类型 广义的封装 狭义的封装


总览
多态
什么是多态?
多态在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

  

猜你喜欢

转载自www.cnblogs.com/cavalier-chen/p/9556438.html