一、封装
什么是封装:
1.封装是面向对象编程的一大特点
2.面向对象编程的第一步:将属性和方法封装到一个抽象的类中(为什么说是抽象的类,因为类不能直接使用)不让用户直接调用,而是开发一些接口间接调用
3.外界使用类创建对象,然后让对象调用方法
4.对象方法的细节都被封装在类的内部
二、继承
1. 继承的定义
继承是一种新建类的方式,新建出来的类我们称为是“子类或者是派生类”,被继承的的类我们称为是“父类或者是基类”当然新建出来类、子类可以遗传父类的所属特性
2. 为什么要用继承
我们首先要知道类解决了什么问题:对象与对象之间的代码冗余问题
然后就是继承可以解决什么问题:类与类之间的代码冗余问题
3. 怎么使用继承
经典类:没有继承object类的子子孙孙都是经典类
新式类:继承了object类的子子孙孙都是新式类
注:在python2中才区分经典类和新式类,如果是python3的版本,所有的类都是新式类,也就是说在Python3中默认的类都是继承了object类,在Python3中没有经典和新式类的说法了。
这段代码将告诉你什么是单继承和多继承
class Object():
pass
class Object1():
pass
A类继承了Object的类,A就称为是子类,Object就称为是父类或者叫基类
单继承:一个类只继承一个类,一个类继承了两个或者两个以上的类就是多继承类
class A(Object):
pass
多继承:B就是子类,Object和Object1都是父类
class B(Object, Object1):
pass
print(A.__bases__) # (<class '__main__.Object'>,)
print(B.__bases__) # (<class '__main__.Object'>, <class '__main__.Object1'>)
继承的实际案例
class User(): # 父类里面都是共同属性和功能
school = '北海幼儿园'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Student(User):
def __init__(self, name, age, gender, course=None):
if course is None: # 如果没有传参默认就是空列表
course = []
'''子类里面一定要调用父类__init__方法'''
User.__init__(self, name, age, gender)
self.course = course
def choose_course(self):
print('%s选课成功%s' % (self.name, self.course))
stu = Student('jack', 20, 'male', 'xxx')
print(stu.__dict__)
print(stu.name)
print(stu.age)
print(stu.gender)
print(stu.school)
# 再加一个子类也是一样的操作
class Grade(User):
def __init__(self, name, age, gender, level):
User.__init__(self, name, age, gender)
self.level = level
def choose_course(self, name):
print('%s得了%s分' % (name, 99))
g = Grade('xl', 10, 'male', 5)
print(g.__dict__)
print(g.name)
print(g.age)
print(g.gender)
print(g.school)
4. 单继承下的属性查找
class A():
def f2(self):
pass
class Foo(A):
def __f1(self): # _Foo__f1
print('from Foo.f1')
# def f2(self):
# print('from Foo.f2')
# self.__f1() # _Foo__f1
class Bar(Foo):
def __f1(self): # _Bar__f1
print('from Bar.f1') # from Bar.f1
"""单继承下的属性查找:先从对象自己名称空间中查找,然后去产生这个对象的类中查找,最后去继承的父类中查找."""
obj = Bar()
obj.f2() #
5. 多继承下的属性查找
多继承下分菱形查找和非菱形查找
菱形查找分 经典类 和 新式类
经典类:按照深度优先的查找顺序
新式类:按照广度优先查找
class G: # 在python2中,未继承object的类及其子类,都是经典类
def test(self):
print('from G')
class E(G):
def test(self):
print('from E')
class F(G):
def test(self):
print('from F')
class B(E):
def test(self):
print('from B')
class C(F):
def test(self):
print('from C')
class D(G):
def test(self):
print('from D')
class A(B,C,D):
# def test(self):
# print('from A')
pass
obj = A()
obj.test() # 如上图,查找顺序为:obj->A->B->E->G->C->F->D->object
# 可依次注释上述类中的方法test来进行验证,注意请在python2.x中进行测试
class G(object):
def test(self):
print('from G')
class E(G):
def test(self):
print('from E')
class F(G):
def test(self):
print('from F')
class B(E):
def test(self):
print('from B')
class C(F):
def test(self):
print('from C')
class D(G):
def test(self):
print('from D')
class A(B,C,D):
# def test(self):
# print('from A')
pass
obj = A()
obj.test() # 如上图,查找顺序为:obj->A->B->E->C->F->D->G->object
# 可依次注释上述类中的方法test来进行验证
"""python3中都是新式类,都是广度优先查询"""
6. super和mro的使用
class A:
def test(self):
super().test()
class B:
def test(self):
print('from B')
class C(A, B):
pass
"""mro列表是通过一个C3算法得出来的,我们无需明白底层原理,只需要知道每个类的mro列表到底是什么,然后按照这个列表去查找就行"""
# 在打印mro列表的时候,一定是从起始类开始
c = C()
c.test()
print(C.mro()) # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class object'>]
print(C.__mro__) # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class object'>]
"""mro列表,每个类都有自己的mro列表,怎么查看类的mro列表"""
a = A()
print(A.mro()) # (<class '__main__.A'>, <class 'object'>)
print(A.__mro__)
三、多态和鸭子类型
什么是多态:
同一种事物的多种形态
举例:
水:气态水、液态水、固态水
动物:人、狗、猪、等都是动物的一种形态(之所以说人、狗、猪、等都是动物,是因为它们都具备动物特征,speak功能)
导入模块
import abc # abstract class 抽象类 具体的Specific
class Animal(metaclass=abc.ABCMeta): # 把animal类变成了抽象类
"""父类中得方法不是为了实现逻辑的,实现功能的,而是单纯的为了限制子类的行为"""
@abc.abstractmethod # 把抽象类中得方法变成抽象方法, 它不实现具体的功能,就是单纯的为了限制子类中的方法
def speak(self):
pass
@abc.abstractmethod
def jiao(self):
pass
"""抽象类和普通类有什么区别? 抽象类只能够被继承、不能够被实例化"""
# Animal() # Can't instantiate abstract class Animal with abstract methods speak
"""怎么限制子类People类必须有speak功能? 我们可以在父类中来限制子类的行为,其实就是限制子类中必须有某些方法"""
class People(Animal):
def speak(self):pass
# print('from People.speak')
def jiao(self):
pass
class Dog(Animal):
def speak(self):
pass
class Pig(Animal):
def speak(self):
pass
"""Python崇尚的是鸭子类型"""
"""鸭子类型就是更多的关注的是对象的行为,而不是对象的类型"""
class People():
def speak(self):pass
# print('from People.speak')
def jiao(self):
pass
class Dog():
def speak(self):
pass
class Pig():
def speak(self):
pass
obj = People()
obj1 = Dog()
obj2 = Pig()
"""多态带来的特性:在不考虑对象类型的情况下,直接调用对象的方法或者属性"""
def animal(obj):
return obj.speak()
animal(obj)
animal(obj1)
animal(obj2)