目录
1.封装-私有与公开权限
2.继承
2.1多继承
2.2继承多层传递
2.3重写父类方法
2.4继承链
2.5禁止私有继承
3.多态
4.总结
1.封装-私有与公开权限
-
公开属性、公开方法:随便调用
-
私有属性、私有方法:
-
只能在类定义的内部调用
-
以两个下划线开头
__
的都是私有权限
-
私有权限:
1- 前面加__来表示是私有
2- 外部无法直接访问私有权限的属性或者方法
3- 在类的内部,可以正常访问私有的属性或者方法
4- 强制访问私有属性或者方法的写法:实例对象名._类名__私有属性或者方法
class Women:""""""def __init__(self, name):self.name = name # 公开属性self.__age = 18 # 私有属性def func1(self):# 公开方法print(self.name)print(self.__age) # 可以调用print(self.__func2()) # 可以调用def __func2(self):# 私有方法print(self.name)print(self.__age)lady = Women('lady gaga')
lady.func1()
# lady.__func2() # 不可以调用
# print(lady.__age) # 不可以调用# 实例对象._类名__属性或方法名 可强行突破!
print(lady._Women__age) # 强行调用私有属性
lady._Women__func2() # 强行调用私有方法
2.继承
-
类的继承:在面向对象编程中,子类可以直接继承父类,从而使子类直接具备父类的能力(属性和方法)【代码复用】
-
继承作用:解决代码重用问题,提高开发效率
-
注意
-
站在父类的角度来看,父类派生出子类
-
站在子类的角度来看,子类继承于父类
-
父类也叫基类,子类也叫派生类
-
object 是 python 中所有类的父类
-
2.1多继承
class SmallDog(object):def eat(self):print('小口吃东西')def sleep(self):print('小憩一会')class BigDog(object):def drink(self):print('大口喝水')def sleep(self):print('呼呼大睡')# 多继承 默认调用先继承的那个父类中的同名方法
# SuperDog 类定义时同时继承了 SmallDog 和 BigDog
class SuperDog(BigDog, SmallDog):pass# 创建一个 SuperDog 对象
sd1 = SuperDog()
# SuperDog 从 SmallDog 继承了 eat 方法
sd1.eat()
# SuperDog 从 BigDog 继承了 drink 方法
sd1.drink()
# 默认调用先继承的那个父类中的同名方法
sd1.sleep()
2.2继承多层传递
# 爷爷类
class Animal(object):"""动物类"""def eat(self):print('吃东西')# 爸爸类
class Dog(Animal):"""狗类"""def drink(self):print('喝水')# 儿子类
class SuperDog(Dog):pass# 创建一个 SuperDog 对象
sd1 = SuperDog()
sd1.eat()
sd1.drink()
2.3重写父类方法
一个类里多个方法都用了同样的名字
重写父类(包括爷爷类及以上)方法:
-
从父类继承的方法不能满足子类的需要,为了拓展功能而重新定义了同名函数
-
重写形式:
-
在子类中定义了一个和父类(包括爷爷类及以上)同名的方法(参数也一样),即为对父类(包括爷爷类及以上)的方法重写
-
-
重写之后子类调用同名方法,默认只会调用子类的
-
类继承存在顺序链:
-
定义类名时从左到右的顺序,左边是右边的子类
-
class SuperDog(SmallDog, BigDog):
这个继承顺序为继承顺序:SuperDog->SmallDog->BigDog
-
-
子类调用父类被重写方法:在子类方法中还想调用父类的同名方法。可以使用如下方式:
-
父类名.同名方法(self, 形参1, ……)
-
super(顺序链目标类左边的类名, self).同名方法(...)
-
class SmallDog(object):def eat(self):print('吃小东西')
class BigDog(object):def eat(self):print('啃大骨头')class SuperDog(SmallDog, BigDog):# todo 继承顺序:SuperDog->SmallDog->BigDogdef eat(self):print('--方式1:父类名.同名方法(self, ...)--')# 需求1:调用 SmallDog 父类的 eat 方法SmallDog.eat(self)# 需求2:调用 BigDog 父类的 eat 方法BigDog.eat(self)print('--方式2:super(顺序链目标类左边的类名, self).同名方法(...)--')# 需求1:调用 SmallDog 父类的 eat 方法super(SuperDog, self).eat()# 需求2:调用 BigDog 父类的 eat 方法super(SmallDog, self).eat()# 本质:super(顺序链上目标父类左边的子类, self).目标父类的同名方法()print('--方式3:super().同名方法(...)--')# 需求1:调用 SmallDog 父类的 eat 方法super().eat() # 与super(SuperDog, self).eat()相同# 类的继承顺序链:在python中,一个类可以继承多个类,
# 而且父类还可能有父类,对于这种情况,类的继承是有一个先后顺序,
# 这个顺序就叫继承顺序链。
# 如何查看一个类的继承顺序链:类名.__mro__
print(SuperDog.__mro__)# 创建一个 SuperDog 对象
sd1 = SuperDog()
sd1.eat()
2.4继承链
class A:def func(self):print("A_的打印输出")class C(A):def func(self):super().func()print("C_的打印输出")class B(A):def func(self):super().func()print("B_的打印输出")class D(B,C):def func(self):super().func()print("D_的打印输出")# 从D角度出发,继承顺序如下:D->B->C->A
# 多继承中,有继承先后顺序,先继承的是第一个父类
d = D()
d.func()
print(D.__mro__)# 输出如下
在D看来,B的爹是C
A类中的func函数
C类中的func函数
B类中的func函数
D类中的func函数
在B看来,B的爹是A
A类中的func函数
B类中的func函数
2.5禁止私有继承
总结:
1- 私有的属性和方法不能被子类继承 (子类可以暴力访问)
2- 面向对象中,封装(私有权限)的主要作用,是用来对外屏蔽一些底层实现细节,对外提供更加安全/好用的方法
举例:PC电脑,只是对消费者暴露键盘、屏幕、USB接口等简单的操作
class Animal:def __init__(self):self.name = '动物'# 私有属性self.__age = 2# 私有方法def __pee(self):print("动物拉粑粑")"""面向对象中,封装(私有权限)的主要作用,是用来对外屏蔽一些底层实现细节,对外提供更加安全/好用的方法举例:PC电脑,只是对消费者暴露键盘、屏幕、USB接口等简单的操作"""def show_info(self):self.__pee()print(self.__age)class Dog(Animal):passd = Dog()
d.show_info()
# d.__pee()
# print(d.__age)# 暴力方式访问(不推荐)
d._Animal__pee()
print(d._Animal__age)
3.多态
同一个代码,由于传入实例对象的不同,最终有不同的调用效果!
# Python是动态语言,站在代码写手的角度,
# 本身就是多态,不存在非多态的情况
def add(a, b):return a + b
res = add(1, 2)
print(res) # 3
res = add('hello', 'world')
print(res) # helloworld
4.总结
面向对象总结:
面向对象的3大特征:封装、继承、多态
定义类的总结:
0- 有多种选择的时候,进入公司后,可能每个小组的编程风格不一样,根据小组风格调整,一般会有代码规范
1- 类的命名:大驼峰命名法。所有单词首字母都大写
2- 所有类的顶级父类,默认是object,可写可不写,一般不写。
魔法方法总结:
1- 常用__init__、__str__、__del__
2- 命名这块,前后都需要有下划线
3- __init__:对类的实例对象进行初始化操作,或者对一些公共资源进行初始化,例如:文件打开、数据库的连接
4- __str__:一般用来对类的实例对象进行格式化输出,返回值类型必须是string。打印对象,默认打印的是内存地址值
5- __del__:在实例对象被删除(通过del)或者被自动销毁(程序运行结束)的时候会调用。一般是用来释放资源
关键字总结:
1- self关键字:它代表是对应的实例对象。不需要手动传值,由python解释器进行赋值
2- cls关键字:在类方法中出现的。它代表的是类
封装总结:
1- 我们进行类的定义、方法的定义,这些操作,都称之为封装
2- 封装里面的私有权限,用来对外部屏蔽类内部的底层细节,不对外暴露
3- 分为私有属性和私有方法。命名的时候在前面使用__,用来表示私有
4- 私有属性和方法,正常只能在类的内部访问
5- 私有属性和方法,可以通过保留方式在类的外部访问。也就是 实例对象名称._类名__私有属性和方法。该方式不推荐
继承总结:
1- 继承:子类从父类中获得相关的方法和属性,该过程称之为继承。不能继承私有属性和方法
2- 继承分类:单继承、多继承、多层继承
3- 继承之后,子类可以重写父类的方法。一般什么情况下会重写?子类需要加强或者改造方法的时候
4- 在子类方法里,调用父类的方法,可以通过如下三种方式:
4.1 (推荐)父类类名.方法名(self,实参1,实参2...)
4.2 super(子类类名,self).方法名(实参1,实参2...)
4.3 super().方法名(实参1,实参2...)
5- 多继承的顺序关系
class A:
class B(A):
class C(A):
class D(B, C):
上面代码的继承关系,【从D的角度出发】,D>B>C>A
多态总结:
1- 多态的含义:多态就是让不同的对象对同一方法有不同的表现
类中的方法总结:
1- 分类:实例方法、类方法、静态方法
2- 实例方法:所有实例对象都能够调用的方法
3- 类方法:
3.1- @classmethod的装饰器。
3.2- 调用的时候,推荐使用类名进行调用。不推荐使用实例对象名进行调用
3.3- 类方法里面只能操作类属性
3.4- 类方法的作用:一般也是用来对公共资源进行初始化操作
4- 静态方法:
4.1- @staticmethod的装饰器
4.2- 调用的时候,推荐使用类名进行调用。不推荐使用实例对象名进行调用
4.3- 静态方法里面不能操作任何类型的属性
4.4- 静态方法的作用:一般也是用来对公共资源进行初始化操作
属性总结:
1- 分类:实例属性、类属性
2- 实例属性:所有实例对象都具备的属性
3- 类属性:类具备的属性。调用的时候,推荐使用类名进行调用。不推荐使用实例对象名进行调用