面向对象---封装,继承,多态

一.继承

类相关的内置函数

  • isinstance() # 判断对象所属类型,包括继承关系
  • issubclass() # 判断类与类之间的继承关系

1.单继承

  1. 实现代码的重用,相同的代码不需要重复的编写
  2. 继承的概念:子类拥有父类的所有方法和属性

继承的语法:

class 类名(父类名):
    pass

特点:

  • 子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发
  • 子类中应该编写自己的任务,封装子类特有的属性和方法
  • 继承的传递性:
  1. 子类拥有父类以及父类的父类中封装的所有属性和方法

专业术语:

子类父类继承
派生类基类派生

2.多继承

  1. 子类 可以拥有 多个父类,并且具有 所有父类 的 属性 和 方法
  2. 语法:
class 子类名(父类名1,父类名2....):
    pass

注意:如果 不同的父类 中存在 同名的方法,子类对象 在调用方法时,会调用哪一个父类中的方法呢?开发时,应该尽量避免这种容易产生混淆的情况! —— 如果 父类之间 存在 同名的属性或者方法,应该 尽量避免 使用多继承。

3.方法的重写

  • 子类拥有父类的所有方法和属性
  • 子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发
  • 当父类的方法不能满足子类的需求时,可以对方法进行重写

重写的方法:

  1. 覆盖父类的方法:在子类中定义一个和父类同名的方法并且实现
  2. 对父类进行扩展
  • 父类原本封装的方法实现 是 子类方法的一部分,就可以使用扩展的方式
  • 在子类中重写父类的方法
  • 在需要的位置使用 super().父类方法 来调用父类方法的执行
  • 代码其他的位置针对子类的需求,编写子类特有的代码实现

调用父类方法的另外一种方式: 父类名.方法(self)

4.父类的 私有属性和私有方法

  • 私有属性、方法 是对象的隐私,不对外公开,外界以及子类都不能直接访问 __属性名\方法
  • 私有属性、方法通常用于做一些内部的事情
  • 子类对象 不能 在自己的方法内部,直接 访问 父类的 私有属性 或 私有方法
  • 子类对象 可以通过 父类 的 公有方法 间接 访问到 私有属性 或 私有方法

5.Python 中的 MRO —— 方法搜索顺序(多继承)

  Python 中针对 类 提供了一个 内置属性 __mro__ 可以查看 方法 搜索顺序MRO 是 method resolution order ,主要用于 在多继承时判断 方法、属性的调用路径

  • print(C.__mro__)
  • 在搜索方法时,是按照 __mro__ 的输出结果 从左至右 的顺序查找的
  • 如果在当前类中 找到方法,就直接执行,不再搜索
  • 如果 没有找到,就查找下一个类 中是否有对应的方法,如果找到,就直接执行,不再搜索
  • 如果找到最后一个类,还没有找到方法,程序报错

6.新式类:以 object 为基类的类,推荐使用 --遵循广度优先
经典类:不以 object 为基类的类,不推荐使用 --遵循深度优先

如果没有父类,建议统一继承自 object

class 类名(object): 
    pass 

这里由于python中木有接口的概念所以制定一个规范抽象类、接口类


二. 多态

python 中处处是多态

  • python 不管什么类型,传入函数,封装到对象中都可以
  • 定义:父类的同一种动作或者行为,在不同的子类上有不同的实现。
  • 作用:
  • 1. 继承将相关概念的共性进行抽象,多态在共性的基础上,体现类型的个性化(一个行为有不同的实现)。
  • 2. 增强程序扩展性,体现开闭原则。重写子类实现了父类中相同的方法(方法名、参数),在调用该方法时,实 际调用的是子类的方法。

三.封装

  1. 封装 是面向对象编程的一大特点 
  2. 面向对象编程的 第一步 —— 将 属性 和 方法 封装 到一个抽象的 类 中 
  3. 外界 使用 类 创建 对象,然后 让对象调用方法 
  4. 对象方法的细节 都被 封装 在 类的内部 

广义封装:实例化一个对象,给对象空间封装一些属性

狭义的封装:私有化,只能在类的内部访问

私有成员:私有静态字段、私有方法、私有对象属性

代码解释·:

class A:
    company_name = 'rose' # 静态变量(静态字段)
    __iphone = '179xxxxxxx' # 私有静态变量(私有静态字段)

    # 第二部分 方法部分
    def __init__(self,name,age): #特殊方法

        self.name = name #对象属性(普通字段) 
        self.__age = age # 私有对象属性(私有普通字段) 

    def func1(self): # 普通方法
        pass

    def __func(self): #私有方法
        print(666)


    @classmethod # 类方法
    def class_func(cls):
        """ 定义类方法,至少有一个cls参数 """
        print('类方法')

    @staticmethod  # 静态方法 23
    def static_func():
        """ 定义静态方法 ,无默认参数"""

        print('静态方法')
    @property  # 属性
    def prop(self):
         pass

1.面向对象的私有与公有

1)对于每一个类的成员而言都有两种形式

  • 公有成员,在任何地方都能访问
  • 私有成员,只有在类的内部才能方法

2)私有成员和公有成员的访问限制不同:

静态字段(静态变量)

  1. 公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
  2. 私有静态字段:仅类内部可以访问;

例子:

1.

class Ke:
    name = "公有静态字段"
    def keke(self):
        print(Ke.name)

class Tou(Ke):
    def show(self):
        print(Ke.name)

a=Ke()
a.keke()
a_1=Tou()
a_1.show()
公有静态字段
公有静态字段

2.

class Ke:
    __name = "私有静态字段"
    def keke(self):
        print(Ke.__name)

class Tou(Ke):
    def show(self):
        print(Ke.__name)

a=Ke()
a.keke()
a_1=Tou()
a_1.show()
私有静态字段
然后报错:私有静态字段不可在派生类中可以访问 

当然:

print(a._Ke__name)

非要访问私有成员的话,可以通过 对象._类__属性名,但是绝对不允许!!!

(为什么可以通过._类__私有成员名访问呢?因为类在创建时,如果遇到了私有成员(包括私有静态字段,私有普通字段,私有方法)它会将其保存在内存时自动在前面加上_类名.)

3.注意:普通字段:

  • 公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问
  • 私有普通字段:仅类内部可以访问;
  • 公有方法:对象可以访问;类内部可以访问;派生类中可以访问
  • 私有方法:仅类内部可以访问;

2面向对象的成员

字段

  1. 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存位置不同,
  2. 普通字段属于对象
  3. 静态字段属于类

代码:

class Province:
# 静态字段 
    country = '中国'

    def __init__(self, name):
    # 普通字段
        self.name = name
#直接访问普通字段
obj = Province('山西省')
print (obj.name)
#直接访问静态字段
print(Province.country)

注意:

  • 静态字段在内存中只保存一份
  • 普通字段在每个对象中都要保存一份
  • 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值