邵邵。

导航

面对对象-继承

回顾

绑定方法

1.绑定给对象
	# 特点:对象调用
    class Student():
        def __init__(self,name,age,gender):
            self.name = name
            self.age = age 
            self.gender = gender
        def choose_course(self):
            pass
    sut = Student('ly',20,'male')
    # 使用类里面的方法,默认绑定给对象
    stu.choose_corse()  # stu.choose_corse(stu) 
2.绑定给类
	# 类调用
    class Student():
        def __init__(self,name,age,gender):
            self.name = name
            self.age = age 
            self.gender = gender
        @classmethod  # 只要加上该装饰器,该方法绑定给类,由类调用,把类名当成第一个参数传入
        def choose_course(cls):
            # cls就是类名
            pass
		# 如果方法里面即需要类,也需要对象,最好绑定给对象
        def func(self):
            print(self)  # 对象
            print(self.__class__)  # 类
            
    
    # 使用类里面的方法,使用@classmethod装饰的函数都是绑定给类
    Student.choose_course()

非绑定方法

# 既不绑定给类,也不绑定给对象。静态方法

class Student():
    @staticmethod  # 静态方法,不管是谁来调用,都不会自动传递参数
    方法名字

隐藏属性

1.如何隐藏属性  __隐藏的名
'''
1.给属性或方法名前加__
2.隐藏对外不对内,外部想要使用,在类内部开放可访问的接口,可以设置限定,对外部做严格的控制,防止外部随意更改内部属性
3.在类的定义阶段发生了语法上的变形,之后的__也不会发生变形
'''

property 装饰器

@proerty
把方法伪装成相对性的属性。
@属性名.setter  # 名字要与相对性的属性名一至
方法


# 了解即可
name = property(方法名1,方法2,方法3)  # 顺序不可乱

面向对象的三大特征

封装

封装
	类似函数,类,将面条版代码封装起来

继承(重要)

1.什么是继承?
		# 继承就是新建类的一种方式,新建的类我们成称为子类或者派生类,被继承的类称之为父类或者基类
		# 子类可以使用父类中的属性或者方法
2.为什么要用继承
		# 类,解决了对象与对象之间的代码冗余问题
		# 继承解决的是类与类之间的代码冗余问题
3.如何使用继承
		新式类:继承了object类的子子孙孙类都是新式类
		经典类:没有继承了object类都是经典类
	# 新式类和经典类之后在python2中区分,Python3中默认都是新式类

怎么使用继承

class Parent1  # 默认继承内置类(object)
	pass
class Parent2  # 所有类都默认
	pass
class Sub1(Parent1):
    pass
class Sub2(Parent1,Parent2)
	pass

__bases__  # 查看子类继承了哪些父类
print(Sub1.__bases__)  # 查看有哪些父类
print(Parent1.__bases__)  # object
学生选课为例
# 父类(公共类)
class People():
	shool = 'SH'
	def __int__(self, name, age, gender)
		self.name = name
		self.age = age
		self.gender = gender

# 学生类
class Student(People):
    def __init__(self, course=None):
		if course is None:
            course = []
		# 学生类与老师类里面相同的属性就可以放在父类中
		People.__init__(self, name, age, gender)  # 就是调用父类的类,不继承也可以正常调用
		self.courses = course
	def choose_course(self,course):
        self.course.append(course)
        print('%s 选课成功 %s' % (self.name, self.courses))
# 老师类
class Teacher(People):
	def __init__(self, level):
		self.level = level
		People.__init__(self, name, age, gender)
		
	def score(self, stu_obj, score):  # 自动传入老师对象,在传入学生对象,然后传入学生分数
		syu_obj.score = score  # 给学生对象添加分数的属性
		print('%s给%s打了%s分' % (self.name, stu_obj.name, score))  
stu = Student()  # 产生一个学生对象
tea = Teacher()  # 产生一个老师对象

继承的属性查找顺序

1.单继承下的属性查找
	对象自身>>产生对象的类>>继承的父类  # 注意隐藏属性的实际是类名加属性名
# 练习1
class Foo:
    def f1(self):
        print('Foo.f1')

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


class Bar(Foo):
    def f1(self):
        print('Bar.f1')


obj = Bar()  # {}
obj.f2()
# 练习2
class Foo:
    def f1(self):
        print('Foo.f1')

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


class Bar(Foo):
    def f1(self):
        print('Bar.f1')


obj = Bar()  # {}
obj.f2()
2.多继承下的属性查找
	# 可恶的菱形查找
	# 了解 
	经典类的查找顺序:多继承情况下,在要查找属性不存在自身的时候,会按照'深度优先'的方式查找下去(最终汇聚的类不能是obj的类)'在继承的父类中左到右依次查找'先最深查询即优先找到最后一个父类
	非菱形查找:没有汇聚的顶端
	# 重要
	新式类查找顺序:多继承,要查找属性不存在时,会按照'广度优先'的方式查找下去,'留一个最深的先不找,到最后一个父类之火在找最深的'
# 练习
class A(object):
	def test(self):
		print('from A')


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

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


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

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


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


f1 = F()
f1.test()

# 新式类:按照广度优先查找
# 经典类:按照深度优先查找

super()和mro()列表

mro() 了解 # 帮助继承属性查找
super():  # 使用遵循mro列表
class People():
    school = 'SH'

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
        
class Teacher(People):

    def __init__(self, name, age, gender, level):
        self.level = level
        super().__init__(name, age, gender) # super的在子类中使用

        
# mro列表练习1
class A:
	def test(self):
		print('from A.test')
		super().test()  # 运行,找到.test()功能


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


class C(A, B):
	pass


c = C()
c.test()  # 查找顺序按照mro列表寻找。


# mro列表练习2 
class B:
    def test(self):
        print('B---->test')

    def aaa(self):  # super().aaa()找到这里
        print('B---->aaa')  # 打印

class A:
    def test(self):  # c.tset()找到这里
        print('A---->test')  # 打印
        super().aaa()  # 然后找.aaa()这个功能,不会回头,会继续在C的另一个父类中寻找


class C(A, B):
    def aaa(self):
        print('C----->aaa')


c = C()
c.test()  # 寻找方法,自身没有,到父类中寻找,找到之后运行
print(A.mro())
	

多态与多态性(了解)

抽象类只能被继承,不能被实例化
import abc  # 调用模块。
class 类名(metaclass = abc.ABCMeta)  # 强制限制
	# 抽象方法
	@abc.abstractmethod  # 加上这个语法糖代表已经是抽象方法了
    def 函数名(self):pass
# 子类必须要有父类中的抽象方法函数名
class Animal(metaclass=abc.ABCMeta):

    @abc.abstractmethod  # 该方法已经是抽象方法了
    def speak(self): pass  # 子类必须存在这个函数名

    @abc.abstractmethod
    def login(self):pass

class People(Animal):
    def speak(self):
        # print('嗷嗷嗷')
        pass
    def login(self):
        pass


class Pig(Animal):
    def speak(self):
        print('哼哼哼')


class Dog(Animal):
    def speak(self):
        print('汪汪汪')


obj = People()
obj.speak()
'Python不推荐这么使用'
多态带来的特性:在不用考虑对象数据类型的情况下,直接调用对象的函数
# 掌握
父类限制子类行为。主动抛异常

	raise 异常名称:
		异常处理
1.什么是多态:
	多种形态:同一类的多种形态
# 多态练习
class Pig():
    def speak(self):
        print('哼哼哼')


class Dog():
    def speak(self):
        print('汪汪汪')

class Txt():
    def speak(self):
        print('Txt')
        
# 墨守成规:相同的类中相似的方法名字要一致
obj = People()
obj1 = Pig()
obj2 = Dog()
obj3 = Txt()

# 多态带来的特性:在不用考虑对象数据类型的情况下直接调用到对应的函数
def animal(animal):
	return animmal.speak()
animal(obj)  # 调用这个函数,然后一个对象,对象使用speak()方法。不会存在方法不存在报错的情况

# 父类限制子类的行为
class Animal():
	def speak(self):
		raise Excepyion('!!!') # 如果对应的子类没有speak()方法。就会抛出异常

posted on 2021-12-06 15:30  邵邵。  阅读(47)  评论(0)    收藏  举报