多态和封装

  • 继承 : 提高代码的重用性,规范代码(要就继承父类的子类都实现相同的方法:抽象类、接口)
  • 当你开始编写两个类的时候,出现了重复的代码,通过继承来简化代码,把重复的代码放在父类中
    • 单继承
      • 重用性 :减少代码的重复,子类可以复用父类的方法
      • 派生 :子类在父类的基础上又创建了自己的新的方法和属性
        • 子类中有父类的同名方法 : 只用子类的
        • 还希望用到父类中的方法 : 父类名、super调用
      • 抽象类 :只能被继承 不能被实例化 模板、规则
from abc import ABCMeta,abstractmethod
class A(metaclass=ABCMeta):
    @abstractmethod
    def func(self):pass
  • 多继承 python / c++

    • java/c#没有
    • 每个类中有每个类能完成的方法
  • 创建子类的时候只需要挑选和我相符合的父类来继承就能够完成父类的功能了

  • 接口 :java中的一种数据类型

  • 经典类和新式类的区别:

    • 经典类 不主动继承object、没有mro方法、没有super、继承的时候 深度优先
    • 新式类 主动继承object、有mro方法、有super、继承的时候 广度优先
  • 方法和函数的区别

    • 只有被对象调用的类中的方法才能被成为一个方法
class A:
    def func(self):pass
a = A()
print(a.func)
print(A.func)
from types import MethodType,FunctionType
print(isinstance(a.func,MethodType))
print(isinstance(a.func,FunctionType))
print(isinstance(A.func,FunctionType))
print(isinstance(A.func,MethodType))

初始化函数 __init__
构造函数 __new__

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('username : ')
        password = input('password : ')
        for  usr in self.user_list:
            if usr.name == username and usr.pwd == password:
                print('登录成功')
                return True


    def register(self):
        username = input('username : ')
        password = input('password : ')
        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
        else:
            print('登录失败')

obj = Account()
obj.run()

多态

1

  • 什么是多态
    • 多态性是指在不考虑实例类型的情况下使用实例
    • 一个类表现出的多种状态 : 通过继承来实现的
    • 在python中:函数的参数不需要指定数据类型,所以我们也不需要通过继承的形式来统一一组类的类型,
      换句话说 所有的对象其实都是object类型,所以在python当中其实处处是多态

2

  • 鸭子类型
  • Python崇尚鸭子类型
    • 如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子

def len(obj)
len() # str list tuple dict set range(3)
print() # 所有的对象都是鸭子类型
不是明确的通过继承实现的多态
而是通过一个模糊的概念来判断这个函数能不能接受这个类型的参数

3

封装

  • 广义上的封装 :对象只能调用自己类的属性和方法
  • 广义上的封装 :把属性函数都放到类里
  • 狭义上的封装 :定义私有成员
class 类名:
    def 方法1(self):pass

是为了只有这个类的对象才能使用定义在类中的方法

  • 仅仅只是一种语法意义上的变形,主要用来限制外部的直接访问
  • 封装的真谛在于明确地区分内外,封装的属性可以直接在内部使用,而不能被外部直接使用
  • 外部要想用类隐藏的属性,需要我们为其开辟接口

把一个名字藏在类中

  • 在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的
#正常情况
>>> class A:
...     def fa(self):
...         print('from A')
...     def test(self):
...         self.fa()
... 
>>> class B(A):
...     def fa(self):
...         print('from B')
... 
>>> b=B()
>>> b.test()
from B
 

#把fa定义成私有的,即__fa
>>> class A:
...     def __fa(self): #在定义时就变形为_A__fa
...         print('from A')
...     def test(self):
...         self.__fa() #只会与自己所在的类为准,即调用_A__fa
... 
>>> class B(A):
...     def __fa(self):
...         print('from B')
... 
>>> b=B()
>>> b.test()
from A
  • 封装方法
  • 目的:是隔离复杂度
class ATM:
    def __card(self):
        print('插卡')
    def __auth(self):
        print('用户认证')
    def __input(self):
        print('输入取款金额')
    def __print_bill(self):
        print('打印账单')
    def __take_money(self):
        print('取款')

    def withdraw(self):
        self.__card()
        self.__auth()
        self.__input()
        self.__print_bill()
        self.__take_money()

a=ATM()
a.withdraw()
  • 私有变量不能被继承,不能在外部定义

  • 类中的私有成员:

    • 私有的静态属性
    • 私有的对象属性
    • 私有的方法
  • 我为什么要定义一个私有变量呢:

    • 我不想让你看到这个值
    • 我不想让你修改这个值
    • 我想让你在修改这个值得时候有一些限制,保证了数据的安全
    • 有些方法或者属性不希望被子类继承
  • property是一个装饰器函数 ---># 将一个方法伪装成一个属性

  • 装饰器的分类:
    装饰函数
    装饰方法 : property
    装饰类

class Student:
    def __init__(self,name,age):
        self.__name = name
        self.age = age
    @property   # 将一个方法伪装成一个属性
    def name(self):
        return self.__name
a = Student('诸葛',20)
print(a.name)
  • 判断是函数还是方法

    from types import FunctionType,MethodType
    
  • property
    一个方法被伪装成属性之后
    应该可以执行一个属性的增删改查操作
    那么增加和修改 就对应这被setter装饰的方法 :这个方法又一个必传的参数new,表示赋值的时候等号后面的值
    删除一个属性 对应着 被deleter装饰的方法,这个方法并不能在执行的时候真的删除这个属性,而是你在代码中
    执行什么就有什么效果

class Goods:
    __discount = 0.8
    def __init__(self,price):
        self.__price = price
        self.name = 'apple'

    @property
    def price(self):
        return self.__price * Goods.__discount

    @price.setter
    def price(self,new):
        self.__price = new   #改变私有对象属性的值

    @price.deleter           #删除私有对象属性
    def price(self):
        del self.__price

apple = Goods(10)         #实例化
print(apple.price)
print(apple.__dict__)

del apple.price
apple.price = 8           #改变私有对象属性
print(apple.price)
print(apple.__dict__)


del apple.name           #删除
print(apple.__dict__)

运行结果

8.0
{'_Goods__price': 10, 'name': 'apple'}
6.4
{'name': 'apple', '_Goods__price': 8}
{'_Goods__price': 8}

Process finished with exit code 0

  • @classmethod 类方法
  • 类方法的特点
    • 只使用类中的资源,且这个资源可以直接用类名引用的使用,那这个方法应该被改为一个类方法
class Goods:
    __discount = 0.8           # 静态属性
    def __init__(self,price):
        self.__price = price   #  对象属性
        self.name = 'apple'

    @property
    def price(self):
        print(self)
        return self.__price * Goods.__discount

    @classmethod
    def change_discount(cls,new):       # 类方法
        cls.__discount = new
  • @staticmethod 静态方法
class Student:

    @staticmethod
    def login(usr,pwd):
        print('IN LOGIN',usr,pwd)


Student.login('user','pwd')
  • 在类中:
    • 静态属性 类 所有的对象都统一拥有的属性
    • 类方法 类 如果这个方法涉及到操作静态属性、类方法、静态方法 cls 表示类
    • 静态方法 类 普通方法,不使用类中的命名空间也不使用对象的命名空间 : 一个普通的函数 没有默认参数
    • 方法 对象 self 表示对象
    • property方法 对象
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,101评论 1 32
  • 一:java概述: 1,JDK:Java Development Kit,java的开发和运行环境,java的开发...
    慕容小伟阅读 1,789评论 0 10
  • 整理来自互联网 1,JDK:Java Development Kit,java的开发和运行环境,java的开发工具...
    Ncompass阅读 1,538评论 0 6
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,386评论 8 265
  • (万尚学习会)打卡第14天 姓名:何炳 部门:业务部 组别:待定 【知~学习】 诵读《道盛和夫自传》第二章 直面石...
    CrisWellin阅读 240评论 0 2