day04.07

动态方法与静态方法

动态方法

  • 绑定给对象的方法
class Student:
    def run(self):
      prtin(self)
# 类调用绑定给对象的方法:有几个参数就需要传几个参数
    Student.run(123)
# 对象调用绑定给对象的方法:会自动将对象当做第一个参数传入
    obj1.run()

 

  • 绑定给类的方法
复制代码
class Student:
  @classmethod
  def eat(cls):
    prtin(cls)
# 类调用绑定给类的方法:会自动将类当做第一个参数传入
  print(Student)  # <class '__main__.Student'>
  Student.eat()  # <class '__main__.Student'>
# 对象调用绑定给类的方法:也不需要传参,会将产生该对象的类自动当做第一个参数传入
  obj1.eat()  # <class '__main__.Student'>
复制代码

 

静态方法

复制代码
class Student:
  @staticmethod
  def speak(a):
    print(a)
# 普普通通的函数:无论谁来调 都必须传固定的参数个数
# 类调用静态方法:要自己传值
Student.speak(123)
# 对象调用静态方法:要自己传值
obj1.speak(321)
复制代码

面向对象的三大特征(继承、封装、多态)

继承

继承的含义:

在面向对象中,继承则是用来描述类与类之间数据的从属关系。

eg:类A继承了类B,那么类A就可以使用类B中所有的数据和功能

继承的目的:

在面向对象中,可以通过继承减少代码冗余,提升开发效率,面向对象中同时也可以支持多继承。

eg:类A可以继承多个类,同时拥有多个类里面的代码使用权(变量名称和功能等等)

继承的基本使用:

class A:    # 我们将被继承的类称为:父类或者基类 A
    pass
class B(A):    # 继承别人的类称为:子类或者派生类 B
    pass
# 在python中一个类可以同时继承多个父类
class F(A,B,C):    # A,B,C都是被继承的类,也就是父类;而F则是继承别人的类,也就是子类
    pass

继承的本质:

在面向对象编程中,其实类和父类的主要功能都是用来减少代码冗余的。

对象:数据与功能的结合体。

类:多个对象具有相同数据和功能的结合体。

父类:多个类具有相同数据和功能的结合体。

由下往上抽取相同特征,叫做抽象;由上往下直接获取利用数据和功能,叫做继承。

复制代码
class Person:    # 父类
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender


class Teacher(Person):    # 子类>>>继承
    def teach(self):
        print(f'{self.name}老师正在讲课')


class Student(Person):    # 子类>>>继承
    def study(self):
        print(f'{self.name}学生正在学习')


stu1 = Student('jason', 18, 'male')
复制代码

面向对象编程时名称的查找顺序:

不存在继承关系的时候:

名字的查找顺序是>>>:先从对象自己的名称空间中查找,如果没有则去类里面的名称空间查找。由对象到类。

Ps:注意设置值的情况下是在自身的名称空间中添加或者修改数据!!!

复制代码
class Student:
    school = '清华大学'
    def choice_course(self):
        print('学生选课')


stu1 = Student()
stu2 = Student()
print(stu1.school)    # 清华大学
print(stu2.school)    # 清华大学
print(Student.school)    # 清华大学
stu1.school = '北京大学'    # stu1.__dict__['school'] = '北京大学'
stu2.school = '南京大学'    # stu1.__dict__['school'] = '南京大学'
Student.school = '复旦大学'    # Student.__dict__['school'] = '复旦大学'
print(stu1.school)    # 北京大学
print(stu2.school)    # 南京大学
print(Student.school)    # 清华大学
复制代码

 

存在单继承的情况:

名字的查找顺序是>>>:先从对象自己的名称空间中查找,如果没有则去产生对象的类的名称空间中查找。如果还没有,并且类有父类,则去父类中查找。由对象到类再到父类。

eg:实例展示

复制代码
class A:

    def f1(self):
        print('from A.f1')

    def f2(self):
        print('from A.f2')
        self.f1()  # 看到self.xx   >>>  要先确认self指的是谁


class MyClass(A):
    def f1(self):
        print('from MyClass.f1')


# 执行的方法分别是A里面的f2和MyClass里面的f1
obj = MyClass()  # from A.f2
obj.f2()  # from MyClass.f1
复制代码

多继承情况下的名称查找:(了解)

在python2中存在经典类与新式类;在python3中只有新式类。

二者区分的关键在于是否继承了一个默认的object类>>>:新式类:直接或者间接继承了object或者其子类的类;经典类:不继承任何的类

object就相当于一个不具有任何实际功能的类。
为了兼容py2和py3,通常写法:
class MyClass(object):
    pass

非菱形结构的多继承情况:

父类中名字的查找顺序就是按照继承时从左往右依次查找>>>如果多个父类还有父类,那么就遵循"深度优先"的原则>>>:即一条路走到黑,如果不存在,再选择另一条路继续走到黑

 

 

菱形结构的多继承情况:

父类中名字的查找顺序就是按照继承时从左往右依次查找>>>如果多个父类还有父类,那么就遵循"广度优先"的原则>>>:即先从左到右查找就近的父类,如果不存在,再选择远端的父类从左到右依次查找

 

 

!!!名字的查找顺序永远都是 先从当前对象自身开始查找!!!

派生类

派生类就是指自己调用父类的功能之后,自己还需要创建额外的功能的类就是派生类。派生类的本质也是子类。

子类需要使用父类的方法,并且还需要基于该方法做扩展,这样的子类我们称之为派生类。

使用super关键字来实现。

super关键字语法结构:
super().__init__(参数1,参数2,参数3....)

派生类实例:

复制代码
class Person:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender


class Teacher(Person):
    def __init__(self, name, age, gender, level, salary):
        # 用了Person类里面的__init__方法之后
        # super(Teacher,self).__init__(name,age,gender)  # 子类调用父类的方法>>>完整语法
        super().__init__(name, age, gender)  # 子类调用父类的方法>>>精简语法    用到super关键字
        # 自己还要添加一个额外的东西
        self.level = level
        self.salary = salary


class Student(Person):
    def __init__(self, name, age, gender, stu_id, class_id):
        # 用了Person类里面的__init__方法之后
        super().__init__(name, age, gender)
        # 自己还要添加一个额外的东西
        self.stu_id = stu_id
        self.class_id = class_id


t1 = Teacher('jason', 18, 'male', '满级', 3.1)
s1 = Student('kevin', 28, 'female', 1302010201, 2)
print(t1.__dict__)    # {'name': 'jason', 'age': 18, 'gender': 'male', 'level': '满级', 'salary': 3.1}
print(s1.__dict__)    # {'name': 'kevin', 'age': 28, 'gender': 'female', 'stu_id': 1302010201, 'class_id': 2}
复制代码

派生功能的前瞻

复制代码
class MyClass(list):
    def append(self,args):
        if args == 123:
            print('数字123不能追加')
            return
        super(MyClass, self).append(args)
obj1 = MyClass()
obj1.append(333)
obj1.append(222)
obj1.append(123)
print(obj1)    # [333,222]
复制代码

可以利用派生功能在原有的内置方法当中添加或者修改符合自己需求的方法,在极大的拓展了原有内置方法的功能的同时,也能精简代码操作,使得功能更加多元化。

 

posted @   *sunflower*  阅读(66)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示