一、封装

1、封装概念

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

**

2、身份运算符

当判断一个变量是否为None时,最好使用 is

运算符 描述 实例
is is 是判断两个标识符是不是引用同一个对象 x is y , 类似 id(x) == id(y)
is not is not 是判断两个标识符是不是引用不同对象 x is not y 类似 id(a) != id(b)

2.1 is 和 == 的区别

is 用来判断两个变量引用对象是否为同一个
== 用于判断 引用变量的值 是否相等

  1. a = [1, 2, 3]
  2. b = [1, 2, 3]
  3. # 用来判断变量指向的对象是否一致,这里不一致
  4. print(a is b) # False
  5. # 判断变量内部元素是否一致
  6. print(a == b) # True

3、私有属性和私有方法

  • 在实际开发中,对象某些属性或方法 可能只希望在对象的内部被使用,而不希望在外部被访问到

**

  • 私有属性就是对象不希望公开的属性

**

  • 私有方法就是对象不希望公开的方法

**

  • python中没有真正意义上的私有。对象.类名._方法名

3.1 定义方式

定义属性方法上,在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法

  1. class Animal:
  2. def __init__(self):
  3. # 私有属性
  4. self.__name = "张三"
  5. def __do_some(self):
  6. print("私有方法,外部不允许调用")

二、继承

1、单继承


继承的概念子类拥有父类以及父类的父类的所有方法属性**

语法:
class 类名(父类名):

  1. class Animal:
  2. def eat(self):
  3. print("吃饭")
  4. def drink(self):
  5. print("喝水")
  6. # 狗类继承动物类,语法 : class 类名(父类名):
  7. class Dog(Animal):
  8. def speak(self):
  9. print("汪汪汪")
  10. xiaotianquan = Dog()
  11. xiaotianquan.eat()
  12. xiaotianquan.drink()
  13. xiaotianquan.speak()
  • 子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发


  • 子类中应该根据职责,封装子类特有的属性和方法

2、方法的重写

  • 父类的方法实现不能满足子类的需求时,可以对方法进行重写(override)

**

  • 重写父类方法有两种情况:
    1. 覆盖父类的方法
    2. 对父类方法进行拓展

2.1 覆盖父类的方法

  • 如果在开发中,父类的方法实现子类的方法实现完全不同

**

  • 就可以使用覆盖的方时,在子类中重新编写父类的方法实现


  • 具体的实现方式:在子类中定义一个和父类同名的方法并且实现即可

**

  • 重写之后,在运行时,只会调用子类中重写的方法,而不会调用父类封装的方法
  1. class Animal:
  2. def speak(self):
  3. print("呼呼呼")
  4. class Dog(Animal):
  5. # 对父类的方法不满意,在这里进行重写
  6. def speak(self):
  7. print("汪汪汪")
  8. xiaotianquan = Dog()
  9. xiaotianquan.speak()

2.2 对父类的方法进行扩展

  1. 如果在开发中,子类的方法实现包含父类的方法实现
    1. 父类原本封装的方法实现子类方法的一部分


  1. 就可以使用拓展的方式
    1. 在子类中重写父类的方法
    2. 在需要的位置使用 super().父类方法 来调用父类方法的执行
    3. 代码其他的位置针对子类的需求,编写子类特有的代码实现 ```python class Animal: def speak(self): print(“呼呼呼”)

class Dog(Animal):

  1. # 对父类的方法不满意,在这里进行重写
  2. def speak(self):
  3. super(Dog, self).speak()
  4. print("汪汪汪")

xiaotianquan = Dog() xiaotianquan.speak()

  1. <a name="dvYpx"></a>
  2. ### 2.3 关于super
  3. - 在python中super是一个** 特殊的类**
  4. **
  5. - super() 就是使用 super类创建出来的对象
  6. - 最常用的场景就是在**重写父类方法时**,调用**父类中封装的方法实现**
  7. <a name="5rDG0"></a>
  8. ## 3、父类的私有属性和私有方法
  9. **子类对象不能**在自己的方法内部,**直接**访问父类的**私有属性**或者**私有方法**<br />**<br />**子类对象**可以通过**父类**的**公有方法 间接**访问到**私有属性** 或 **私有方法**
  10. > **私有属性,方法**> _是对象的隐私,不对外公开,_> **外界以及子类**> _都不能直接访问_> **> **私有属性,方法**> _通常用于做一些内部的_> **事情**
  11. <a name="P5H4o"></a>
  12. ## 4、多继承
  13. python中支持多继承<br />**子类**可以拥有**多个父类**,并且具有**所有父类的属性**和**方法**<br />**<br />语法:<br />class 子类名(父类名1,父类名2。。。):<br />pass
  14. ```python
  15. class Father:
  16. def father(self):
  17. print("我是爸爸")
  18. class Mother:
  19. def monther(self):
  20. print("我是妈妈")
  21. # 多继承语法:
  22. class Son(Father, Mother):
  23. pass
  24. xiaoming = Son()
  25. # Sun类 同时有Father继承过来的方法,也有Mother继承过来的方法
  26. xiaoming.father()
  27. xiaoming.monther()

4.1 多继承的使用注意事项

  • 如果不同的父类中存在同名的方法子类对象在调用方法时,会调用哪一个父类中的方法呢


  • 提示:在开发时应该尽量避免这种容易产生混淆的情况,如果父类之间存在同名的属性或者方法,应该尽量避免使用多继承

_

在搜索方法时,是按照 mro_的输出结果 从左向右 的顺序查找的_

5、新式类和经典类

  • 新式类:以object为基类的类,推荐使用

**

  • 经典类:不以object为基类的类,不推荐使用

**

  • 新式类和经典类子啊多继承是 会影响到方法的搜索顺序

_

  • 为了保证以后编写的代码能够同时在 python2.x 和 python3.x 中运行


  • 今后在定义类时,如果没有父类,建议统一继承object

class类名(object):
pass

三、多态

多态 不同的子类对象 调用相同的父类方法,产生不同的执行结果

  • 多态可以增加代码的灵活度

**

  • 继承重写父类方法为前提


  • 时调用方法的技巧,不会影响到类的内部设计
  1. class Dog(object):
  2. def __init__(self, name):
  3. self.name = name
  4. def play(self):
  5. print("%s 蹦蹦跳跳的玩耍" % self.name)
  6. class XiaoTianDog(Dog):
  7. # 重写父类的方法
  8. def play(self):
  9. print("%s 飞到了天上玩" % self.name)
  10. class Person(object):
  11. def __init__(self, name):
  12. self.name = name
  13. # 多态的体现
  14. def play_with_Dog(self, dog):
  15. print("%s 和 %s 愉快的玩耍" % (self.name, dog.name))
  16. dog.play()
  17. xt = XiaoTianDog("哮天犬")
  18. xiaoming = Person("小明")
  19. xiaoming.play_with_Dog(xt)

1、术语 — 实例

  • 使用面向对象开发,第一步 是设计

**

  • 使用类名()创建对象,创建对象的动作有两部
    1. 在内存中为对象分配空间
    2. 调用初始化方法 init对象初始化

**

  • 对象创建后,内存中就有了一个对象的实实在在的存在 —- 实例
  • 创建出来的对象叫做实例
  • 创建对象的动作叫做实例化
  • 对象的属性叫做实例属性
  • 对象调用的方法叫做 实例方法

    2、结论:

  1. 每一个对象都有自己独立的内存空间保存各自不同的属性
  2. 多个对象的方法,在内存中只有一份,在调用方法时,需要把对象的引用传递到方法内部