一、封装
1、封装概念
- 封装是面向对象编程的一大特点
- 面向对象编程的第一步 — 将属性和方法封装到一个抽象的类中
- 外界使用类创建 对象,然后让对象调用方法
- 对象方法的细节都被封装在类的内部
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 用来判断两个变量引用对象是否为同一个
== 用于判断 引用变量的值 是否相等
a = [1, 2, 3]
b = [1, 2, 3]
# 用来判断变量指向的对象是否一致,这里不一致
print(a is b) # False
# 判断变量内部元素是否一致
print(a == b) # True
3、私有属性和私有方法
- 在实际开发中,对象的某些属性或方法 可能只希望在对象的内部被使用,而不希望在外部被访问到
**
- 私有属性就是对象不希望公开的属性
**
- 私有方法就是对象不希望公开的方法
**
- python中没有真正意义上的私有。对象.类名._方法名
3.1 定义方式
在定义属性或方法上,在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法
class Animal:
def __init__(self):
# 私有属性
self.__name = "张三"
def __do_some(self):
print("私有方法,外部不允许调用")
二、继承
1、单继承
继承的概念:子类拥有父类以及父类的父类的所有方法和属性**
语法:
class 类名(父类名):
class Animal:
def eat(self):
print("吃饭")
def drink(self):
print("喝水")
# 狗类继承动物类,语法 : class 类名(父类名):
class Dog(Animal):
def speak(self):
print("汪汪汪")
xiaotianquan = Dog()
xiaotianquan.eat()
xiaotianquan.drink()
xiaotianquan.speak()
- 子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发
- 子类中应该根据职责,封装子类特有的属性和方法
2、方法的重写
- 当父类的方法实现不能满足子类的需求时,可以对方法进行重写(override)
**
- 重写父类方法有两种情况:
- 覆盖父类的方法
- 对父类方法进行拓展
2.1 覆盖父类的方法
- 如果在开发中,父类的方法实现和子类的方法实现,完全不同
**
- 就可以使用覆盖的方时,在子类中重新编写父类的方法实现
- 具体的实现方式:在子类中定义一个和父类同名的方法并且实现即可
**
- 重写之后,在运行时,只会调用子类中重写的方法,而不会调用父类封装的方法
class Animal:
def speak(self):
print("呼呼呼")
class Dog(Animal):
# 对父类的方法不满意,在这里进行重写
def speak(self):
print("汪汪汪")
xiaotianquan = Dog()
xiaotianquan.speak()
2.2 对父类的方法进行扩展
- 如果在开发中,子类的方法实现中包含父类的方法实现
- 父类原本封装的方法实现 是 子类方法的一部分
- 就可以使用拓展的方式
- 在子类中重写父类的方法
- 在需要的位置使用 super().父类方法 来调用父类方法的执行
- 代码其他的位置针对子类的需求,编写子类特有的代码实现 ```python class Animal: def speak(self): print(“呼呼呼”)
class Dog(Animal):
# 对父类的方法不满意,在这里进行重写
def speak(self):
super(Dog, self).speak()
print("汪汪汪")
xiaotianquan = Dog() xiaotianquan.speak()
<a name="dvYpx"></a>
### 2.3 关于super
- 在python中super是一个** 特殊的类**
**
- super() 就是使用 super类创建出来的对象
- 最常用的场景就是在**重写父类方法时**,调用**父类中封装的方法实现**
<a name="5rDG0"></a>
## 3、父类的私有属性和私有方法
**子类对象不能**在自己的方法内部,**直接**访问父类的**私有属性**或者**私有方法**<br />**<br />**子类对象**可以通过**父类**的**公有方法 间接**访问到**私有属性** 或 **私有方法**
> **私有属性,方法**> _是对象的隐私,不对外公开,_> **外界以及子类**> _都不能直接访问_> **> **私有属性,方法**> _通常用于做一些内部的_> **事情**
<a name="P5H4o"></a>
## 4、多继承
python中支持多继承<br />**子类**可以拥有**多个父类**,并且具有**所有父类的属性**和**方法**<br />**<br />语法:<br />class 子类名(父类名1,父类名2。。。):<br />pass
```python
class Father:
def father(self):
print("我是爸爸")
class Mother:
def monther(self):
print("我是妈妈")
# 多继承语法:
class Son(Father, Mother):
pass
xiaoming = Son()
# Sun类 同时有Father继承过来的方法,也有Mother继承过来的方法
xiaoming.father()
xiaoming.monther()
4.1 多继承的使用注意事项
- 如果不同的父类中存在同名的方法,子类对象在调用方法时,会调用哪一个父类中的方法呢
- 提示:在开发时,应该尽量避免这种容易产生混淆的情况,如果父类之间存在同名的属性或者方法,应该尽量避免使用多继承
_
在搜索方法时,是按照 mro_的输出结果 从左向右 的顺序查找的_
5、新式类和经典类
- 新式类:以object为基类的类,推荐使用
**
- 经典类:不以object为基类的类,不推荐使用
**
- 新式类和经典类子啊多继承是 会影响到方法的搜索顺序
_
- 为了保证以后编写的代码能够同时在 python2.x 和 python3.x 中运行
- 今后在定义类时,如果没有父类,建议统一继承object
class类名(object):
pass
三、多态
多态 不同的子类对象 调用相同的父类方法,产生不同的执行结果
- 多态可以增加代码的灵活度
**
- 以继承和重写父类方法为前提
- 时调用方法的技巧,不会影响到类的内部设计
class Dog(object):
def __init__(self, name):
self.name = name
def play(self):
print("%s 蹦蹦跳跳的玩耍" % self.name)
class XiaoTianDog(Dog):
# 重写父类的方法
def play(self):
print("%s 飞到了天上玩" % self.name)
class Person(object):
def __init__(self, name):
self.name = name
# 多态的体现
def play_with_Dog(self, dog):
print("%s 和 %s 愉快的玩耍" % (self.name, dog.name))
dog.play()
xt = XiaoTianDog("哮天犬")
xiaoming = Person("小明")
xiaoming.play_with_Dog(xt)
1、术语 — 实例
- 使用面向对象开发,第一步 是设计类
**
- 使用类名()创建对象,创建对象的动作有两部
- 在内存中为对象分配空间
- 调用初始化方法 init为对象初始化
**
- 对象创建后,内存中就有了一个对象的实实在在的存在 —- 实例
- 每一个对象都有自己独立的内存空间,保存各自不同的属性
- 多个对象的方法,在内存中只有一份,在调用方法时,需要把对象的引用传递到方法内部