面向对象三大特征

面向对象三大特征

 

封装  

  1.什么是封装?

    封装:就是把数据和功能整合在一起  通俗点说就是整合

    针对封装到类和对象中的属性,我们还可以严格控制对他们的访问,分两步实现:隐藏和开放接口

  2.隐藏属性

    1.如何隐藏    

      __名称(类名称空间内的)

      __school

    2.隐藏属性发生了什么?

      1. 在类定义阶段,发生了语法上的变形_类名__属性名

      2. 隐藏对外不对内

      3. 只有在类定义阶段发生变形,其他情况都不发生变形了

    3.为何隐藏

      类里面的隐藏属性, 类外部可以使用,但是目的不是让类外部使用的,类外部要是想用,在类内部开放接口进行访问

      可以达到对外部数据的严格控制

    4.实例

class Student():
    __school = 'SH' # _Student__school  => _类名__属性名
    def __init__(self, name, age):
        self.__name = name
        self.age = age

    def __tell_info(self):  # _Student__tell_info  => _类名__函数名
        print('name: %s, age: %s' % (self.__name, self.age))

    def get_school(self):
        return self.__school  # self._Student__school

    def set_school(self, v):
        if type(v) is not str:
            print('数据类型不合法')
        # if isinstance(v, str):
            return
        self.__school = v

  3.property装饰器

    把方法伪装成属性

    1.标准方法(魔法糖法)

class Student():
    __school = 'SH'  # _Student__school  => _类名__属性名

    def __init__(self, name, age):
        self.__name = name
        self.age = age

    def __tell_info(self):  # _Student__tell_info  => _类名__函数名
        print('name: %s, age: %s' % (self.__name, self.age))

    @property  # 把方法伪装成属性
    def name(self):
        return "name:%s" % self.__name

    @name.setter
    def name(self, v):
        if type(v) is not str:
            print('数据类型不合法')
        # if isinstance(v, str):
            return
        self.__name = v

    @name.deleter
    def name(self):
        print('不让删')

stu = Student('ly', 18)
print(stu.get_name())

stu.name = 123
print(stu.name)

del stu.name

    2.小练习

class Bmi():
    def __init__(self, height, weight):
        self.height = height
        self.weight = weight

    @property
    def get_bmi(self):
        return self.weight / (self.height ** 2)

bmi = Bmi(1.8, 70)
print(bmi.get_bmi)

    3.了解(顺序问题)

class Student():
    __school = 'SH'  # _Student__school  => _类名__属性名

    def __init__(self, name, age):
        self.__name = name
        self.age = age

    def __tell_info(self):  # _Student__tell_info  => _类名__函数名
        print('name: %s, age: %s' % (self.__name, self.age))

    def get_name(self):
        return "name:%s" % self.__name

    def set_name(self, v):
        if type(v) is not str:
            print('数据类型不合法')
            # if isinstance(v, str):
            return
        self.__name = v

    def del_name(self):
        print('不让删')
    
    # 了解  # 有顺序问题
    name = property(get_name, set_name, del_name)


stu = Student('ly', 18)
print(stu.xxx)

stu.name = 'aaa'
print(stu.name)

继承(重要)

  1.什么是继承?

    继承:就是新建类的一种方式,新建的类我们称为子类或者叫派生类,被继承的类我们称为父类或者基类

    子类可以使用父类中的属性或者方法

  2.为什么要用继承?

    类:解决了对象与对象之间的代码冗余问题

    继承:解决的是类与类之间的代码冗余问题

  3.如何使用继承?

    新式类:

      继承了object类的子子孙孙类都是新式类

    经典类:

      没有继承了object类的子子孙孙类都是经典类

    新式类和经典类只有在python2中区分

    在python3中都是新式类

  4.类的继承

    以学生选课系统为例

    # 父类,公共类

class People():
    school = 'SH'

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

    # 学生类

class Student(People):

    def __init__(self, name, age, gender, course=None):
        if course is None:
            course = []
        People.__init__(self, name, age, gender)
        self.courses = course

    def choose_course(self, course):
        self.courses.append(course)
        print('%s 选课成功 %s' % (self.name, self.courses))

stu = Student('ly', 19, 'male')

    # 老师类

class Teacher(People):

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

    def score(self, stu_obj, score):
        stu_obj.score = score  # 给学生打分
        print('%s给%s打了%s分' % (self.name, stu_obj.name, score))

tea = Teacher('ly', 19, 'male', 10)
print(tea.name)
print(tea.level)

  5.怎么查看继承的所有父类

    print(类名.__bases__)
print(类名.__bases__)

  6.继承的属性查找顺序

    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()

      # 练习

class Foo:
    def __f1(self):  # _Foo__f1()
        print('Foo.f1')

    def f2(self):
        print('Foo.f2')
        self.__f1()  # _Foo__f1()


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

obj = Bar()  # {}
obj.f2()   

    2.多继承下的属性查找

      新式类:

        按照广度优先查询

      经典类:

        按照深度优先查询

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列表

  super的使用

    super()调用父类并传参(少传自己self参数)

# 父类
class People():
    school = 'SH'
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
# 子类

class Student(People):
    def __init__(self, name, age, gender, course=None):
        if course is None:
            course = []
        self.course = course
        # People.__init__(self, name, age, gender)  # 类来调用方法,就是在电影普通方法,有几个参数就传递几个参数
        # super(Student, self) 返回的是一个特殊的对象
        # super(Student, self).__init__(name, age, gender) # python2中写法
        super().__init__(name, age, gender) 
        
 Student.mro()    

  mro列表

    练习1

class A:
    def test(self):
        print('from A.test')
        super().test()


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


class C(A, B):
    pass


c = C()
# c.test()
print(A.mro())

    练习2 

class B:
    def test(self):
        print('B---->test')

    def aaa(self):
        print('B---->aaa')

class A:
    def test(self):
        print('A---->test')
        super().aaa()


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


c = A()
# c.test()  # 打印结果:
print(A.mro())

多态

  1. 什么是多态

    水:液态水,固态水,气态水

    动物:人,猪,狗,猫 ...

    多态:指的是一种事物的多种形态

    多态中的类目的:不是用来继承父类的属性和方法的,让父类来限制子类的行为

import abc

# 此类已经变为抽象类,
# 抽象类只能被继承,不能被实例化
class Animal(meteclass=abc.ABCMeta):
    @abc.abstractmethod
    def speak(self):
        pass
 
class People(Animal):
    def speak(self):
        pass
class Pig(Animal):
    def speak(self):
        pass


class Dog(Animal):
    def speak(self):
        pass

obj = People()
obj.speak()

  2.python推荐鸭子类型

# python推荐鸭子类型
class People():
    def speak(self):
        pass

class Pig():
    def speak(self):
        pass

class Dog():
    def speak(self):
        pass
    
 obj1 = People()
 obj2 = Pig()
obj3 = Dog()

# obj1.speak()
# obj2.speak()
# obj3.speak()

def animal(animal):
    return animal.speak

animal(obj1)
animal(obj2)
animal(obj3)

  3.多态性

    多态带来的特性:在不用考虑对象数据类型的情况下,直接调用对应的函数

      eg:len()

def animal(animal):
    return animal.speak()

animal(obj)
animal(obj1)
animal(obj2)
animal(obj3)

  4.父类限制子类的行为

# 父类限制子类的行为:
class Animal():
    def speak(self):
        raise Exception('必须实现speak')
 
class People(Animal):
    def speak(self):
        pass

 

END

 

posted @ 2021-12-06 16:22  Snails蜗牛  阅读(50)  评论(0编辑  收藏  举报