8-6继承、在子类中重用父类的功能、属性查找、继承的实现和原理、Mixins机制

===========================重点强调===========================
 类:解决对象之间的冗余问题
        相似的东西放到类中,为多个对象共享

 继承:解决类之间的冗余问题
        为多个类共享



分析对象所具有的属性时,

要站在一定的角度上,围绕着项目中用的上的属性进行总结
    否则,属性是无边无际的

---------------

购物车项目中,原来的tank方式,还是存在循环导入的问题(虽然程序还能跑起来,但是其是存在问题的,故需要进行修改)


避免循环导入的问题的措施:
                        ①登录功能写到 login_auth 里
                        ②使用os.envieron

------------------

代码规范格式要求:在 执行所有核心逻辑之前,

1、先导入内置的模块
import 写一行

2、导入第三方的模块
from ...   import ...    # 写在一起

3、导入自己的模块
from ..   import ...

4、放全局变量

在下面写内容代码




============================继承================================

1 什么是继承
    继承是一种新建类的方式,新建的类称之为子类,被继承的类称之为
    父类、基类、超类

    python支持多继承

2 为何要继承
    子类会遗传父类的属性,所以继承是用来解决类与类之间代码冗余问题

3、如何实现继承

			class Parent1:
			    pass
			
			class Parent2:
			    pass
			
			class Sub1(Parent1):
			    pass
			
			class Sub2(Parent1,Parent2):
			    pass
			
			print(Sub1.__bases__)
			print(Sub2.__bases__)
			
			# __bases__    打印sub的父类


		----继承案列:
			class OldboyPeople:
			    school = "oldboy"


			class Student(OldboyPeople):
			    def __init__(self,name,age,gender,stud_id,course):
			        self.name = name
			        self.age = age
			        self.gender = gender
			        self.stu_id = stud_id
			        self.course = course

			    def choose(self):
			        print('%s 正在选课' %self.name)

			class Teacher(OldboyPeople):
			    def __init__(self,name,age,gender,salary,level):
			        self.name = name
			        self.age = age
			        self.gender = gender
			        self.salary = salary
			        self.level = level

			    def score(self,stu,num):
			        stu.num = num


			stu1=Student("艾利克斯",73,'male',1001,"python全栈开放")
			tea1=Teacher("egon",18,'male',2000,10)


			print(stu1.school)


补充:
		
	子类可以继承、使用父类的任何方法,包括__init__函数




	按照查找优先级找,而不能用就近原则查找

	对象 > 类  > 父类



==========在子类派生的新方法中重用父类的功能=======================

方式一:指名道姓地调用某一个类的函数
	
	特点:不依赖于继承关系

		类定义中,指明道姓的调用其他类的功能
		这种方式不依赖继承
		该类调用了其他类的方法,为该类中的对象,造了若干的数据属性
		从而不借助继承机制,实现继承的效果
		在子类派生的新方法中重用父类的功能


		class OldboyPeople:
		    school = "oldboy"
		    #             空对象,"艾利克斯",73,'male'
		    def __init__(self,name,age,gender):
		        self.name = name
		        self.age = age
		        self.gender = gender

		    def f1(self):
		        print('1111111')

		class Student(OldboyPeople):
		    #            空对象,"艾利克斯",73,'male',1001,"python全栈开放"
		    def __init__(self,name,age,gender,stu_id,course):
		        OldboyPeople.__init__(self,name,age,gender)  # OldboyPeople.__init__(空对象,"艾利克斯",73,'male')
		        self.stu_id = stu_id
		        self.course = course


		    def choose(self):
		        print('%s 正在选课' %self.name)

		    def f1(self):
		        OldboyPeople.f1(self)
		        print("22222")

		class Teacher(OldboyPeople):
		    def score(self,stu,num):
		        stu.num = num


		stu1=Student("艾利克斯",73,'male',1001,"python全栈开放")
		# tea1=Teacher("egon",18,'male',2000,10)


		stu1.f1()

补充:
		class Teacher:
		    def __init__(self, name, age, salary, level):
		        People.__init__(self, name, age, None)
		        self.salary = salary
		        self.level = level
		        self.its_class = []


		当使用这种方式模拟继承的时候:
		原属性名,发生了变形,对于变形的,必须要通过变形之后的名字 才能访问这些属性

		teacher1=Teacher('木木',18,'99k','低级')

		teacher1.__dict__ 中的内容详细:

		{'_People__name': '木木', '_People__age': 18, '_People__gender': None, 'salary': '18k', 'level': '高级', 'its_class': []}


方式2:依赖继承(不推荐)

	继承 的耦合性高
	继承(能少用,还是少用)
	    用时,切勿将继承的层级设置过多

	推荐用非继承方式,实现继承效果的方式




补充:


	函数  不等价于   方法

	没经过classmethod等的处理  都是函数(即 函数就是不具有自动传参self的效果)
	    就是单纯语句的集和,没有自动传值的作用
	经过了处理    叫  方法(即 方法都具有 自动传参self的效果);
	    方法 有自动传值的作用



	实参 与 形参

	定义时,叫 形参
	调用时,叫 实参



============================属性查找======================================

解决覆盖的原则:只要名字不一样便可实现



1、隐藏
隐藏之后,父类、子类中的同名属性便不会产生 覆盖,因为发生了变形 底层的名字不一样
只不过 表面看起来一样



	例1:
		class Foo:
		    def f2(self):
		        print("Foo.f2")

		    def f1(self):
		        print('Foo.f1')
		        self.f2()  # obj.f2()


		class Bar(Foo):
		    def f2(self):
		        print("Bar.f2")




		obj = Bar()

		obj.f1()

		"""
		Foo.f1
		Bar.f2
		"""


	例2:父类如果不想让子类覆盖自己的方法,可以在方法名前加前缀__
		
		class Foo:
		    def __f2(self):  # _Foo__f2
		        print("Foo.f2")

		    def f1(self):
		        print('Foo.f1')
		        self.__f2()  # obj._Foo__f2()


		class Bar(Foo):
		    def __f2(self):  # _Bar__f2
		        print("Bar.f2")




		obj = Bar()

		obj.f1()






2. 直接改名字

        class Foo():
            def foo_f2(self):
                print('我是foo的f2')

            def f1(self):
                print('我是foo的f1')
                self.foo_f2()


        class Bar(Foo):
            def f2(self):
                print('我是bar的f2')


        obj = Bar()
        obj.f1()




============================继承的实现和原理==================================

coding:utf-8



为保证兼容性:在python中手动继承objest

object不在菱形问题的讨论范围



1 补充知识:

	新式类:但凡是继承了object类的子类,以该子类子子孙孙类都称之为新式类
	经典类:没有继承了object类的子类,以该子类子子孙孙类都称之为经典类

	python3中全都是新式类,python2中才有经典类:
	在python3中没有继承任何类的类会默认继承object类
	class Foo(object):
	    pass

	print(Foo.__bases__)

2 继承的实现原理
2.1 菱形问题:一个子类继承的多条件分支最终汇聚到一个非object类,在菱形继承下
              新式类与经典类关于属性查找的方式不同

	新式类:广度优先
	经典类:深度优先


例1:非菱形继承,经典类与新式类的属性查找顺序都一样

		class E:
		    # def test(self):
		    #     print('from E')
		    pass

		class F:
		    def test(self):
		        print('from F')


		class B(E):
		    # def test(self):
		    #     print('from B')
		    pass

		class C(F):
		    def test(self):
		        print('from C')


		class D:
		    def test(self):
		        print('from D')


		class A(B, C, D):
		    # def test(self):
		    #     print('from A')
		    pass

		obj=A()
		obj.test()


例2:菱形继承

		class G(object): # 在python2中,未继承object的类及其子类,都是经典类
		    # def test(self):
		    #     print('from G')
		    pass

		class E(G):
		    # def test(self):
		    #     print('from E')
		    pass

		class F(G):
		    # def test(self):
		    #     print('from F')
		    pass

		class B(E):
		    # def test(self):
		    #     print('from B')
		    pass

		class C(F):
		    # def test(self):
		    #     print('from C')
		    pass

		class D(G):
		    # def test(self):
		    #     print('from D')
		    pass

		class A(B,C,D):
		    # def test(self):
		    #     print('from A')
		    pass

		# obj=A()
		# obj.test()

		print(A.mro())



若无分支(只有单继承),直接一条路去找就行


确定 查找顺序,解决多继承是广度一层一层找,还是深度找

    查找时,object 最后找,即现有的类 都找不到时找object




=============================> mixins机制 <=========================================

这个机制
Mixmin 的一个类,只单纯的表示某一个功能
作用单一


-------------
原本的多继承: 继承关系不清晰

多继承的规范,Mixins机制:

	多个类中,只有一个类是用来表示归属的类(往右放)      
	其他类都是功能类(往左放)    
	类名加上Mixins以标识

	这样做的好处:继承关系看起来更清晰 ,既符合了人的表达方式   
				同时凸显了多继承的好处,最大限度的减少代码的冗余


	通过C3列表中的顺序进行查找
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值