likes
comments
collection
share

动静态方法,继承与派生。

作者站长头像
站长
· 阅读数 13

对象独有的功能(绑定给对象的方法)

class Person:
    h_type = '人类'

    def __init__(self, name):  # 让对象拥有独有的数据
        self.name = name
    # 定义在类中的函数 我们称之为方法
    def eat(self):  # 是多个对象公共的方法 也算多个对象独有的方法  对象来调用就会将对象当做第一个参数传入
        print('%s正在干饭'%self.name)

    def others(self,a,b):
        print('others哈哈哈')

'''
针对对象独有的方法 我们无法真正实现
    1.如果在全局则不是独有的
    2.如果在类中则是公共的
python解释器针对上述问题添加了一个特性:定义在类中的函数默认是绑定给对象的(相当于是对象独有的方法)
'''
# p1 = Person('jason')
# p1.eat()  # eat(p1)
# p2 = Person('kevin')
# p2.eat()  # eat(p2)
# 如何理解绑定二字
# p3 = Person('oscar')
# Person.eat(p3)

p1 = Person('jason')
p1.others(1, 2)
Person.others(p1,1,2)

动静态方法

在类体代码中编写的函数主要分为:
1.绑定给对象的方法
    是定义方法最常用的方式,没有关键字
    如果是对象调用会自动将对象本身(self)当做第一个参数传入,(可以少写一个参数)
    如果是类调用则需要自己传入self参数,(有几个参数写几个)
2.绑定给类的方法
    关键字@classmethod
    绑定给类的方法,无论是对象还是类来调用,都无需传入cls参数,会自动将类本身当做self传入。
3.静态方法
    关键字@staticmethod
    平平无奇的方法,使用频率最低
    不管是类还是对象调用,有几个参数就传几个参数。

 class Student:
    school = '清华大学'
    # 绑定给对象的方法,自带self参数,用于接收对象
    def run(self):
        print(' run ')
    # 绑定给类的方法,自带cls参数,用于接收类
    @classmethod
    def eat(cls):
        print(' eat ')
    # 静态方法  无任何自带参数
    @staticmethod
    def read():
        print(' read ')

stu1 = Student()
# 调用绑定给对象的方法
stu1.run()  # 对象调用会自动将对象本身当做第一个参数传入
Student.run(stu1)  # 类调用需要手动传入一个对象
# 调用绑定给类的方法
stu1.eat()  # 对象调用会自动将产生该对象的类当做第一个参数传入
Student.eat()  # 类调用会自动将类作为第一个参数传入
# 调用静态方法
stu1.read()  # read无需传参,不传就行
Student.read()   

面向对象三大特性之继承

1.继承的含义
    类A继承类B,那么类A就有了B里所有的数据和功能。A称为子类或派生类,B称为父类或基类、超类。子类可以同时继承多个父类。
2.继承的目的
    省略代码的编写,减少重复劳动
3.继承的具体操作
    class 类名(父类名):
        pass
    如果需要继承多个父类,括号内各个父类名称之间用逗号隔开。例如 class MyClass(F1,F2,F3):
	查找属性的顺序按照从左至右即可。
    
class A:
    name = 'jason'
class B(A):
    pass
stu1 = B()
print(stu1.name)  #  jason    类B中没有name属性,但由于父类A里有,所以打印jason   

4.继承相关的名词解释
继承:从上往下白嫖各个父类里的资源
抽象:将多个子类共同拥有的属性和方法抽取出来,形成一个父类。
对象:数据和功能的结合体,由类创造出来(实例化)。
类:  多个对象相同的数据和功能的结合体
父类:多个子类相同的数据和功能的结合体

动静态方法,继承与派生。

动静态方法,继承与派生。

继承时名字的查找顺序

先说结果:对象自身-->创建对象的类-->父类

class A:
    name = 'jason'
class B(A):  # 类B继承类A
    name = 'kevin'
stu1 = B()  # 类B实例化了对象stu1
stu1.name = 'tony'
print(stu1.name)  # tony
1.对象stu1名称空间中有name,那么查找name时会优先取对象名称空间中的那个即输出 tony 
2.若我们注掉 stu1.name = 'tony' ,对象名称空间中没有了叫name的变量名,那么查找时会去找创建stu1的类,也就是类B中查找,即输出 kevin
3.若我们注掉类B中的 name = 'kevin', 对象和类中都没有了name这个变量名,那么查找时会向上找到B的父类A,A中有name,即输出 jason
4.如果注掉A中的 name = 'jason' , 三者中都没有name,那么就会报错。

动静态方法,继承与派生。

经典类与新式类

经典类
	不继承object或其子类的类(什么都不继承)
新式类
	继承了object或其子类的类
"""
在python3中所有的类默认都会继承object
	也就意味着python3里面只有新式类
在python2中有经典类和新式类
	由于经典类没有核心的功能 所以到了python3直接砍掉了
	
以后我们在定义类的时候  如果没有想要继承的父类 一般推荐以下写法
    class MyClass(object):
        pass
目的是为了兼容python2
"""
以后写代码针对object无需关心 知道它的存在即可

派生方法

有时候,我们不满足于父类拥有的方法,向基于父类再多加一些自己的功能,那么这个操作就叫做'派生'
派生关键字super()
'调用super()会得到一个特殊的对象,该对象专门用来引用父类的属性'
# 需求:修改列表的append方法,使其不能添加'kevin'字符串
class MyClass(list):
    def append(self, value):
        if value == 'kevin':
            print('kevin不能被追加')
            return
        super().append(value)
obj = MyClass()
obj.append('kevin')
obj.append('jason')
print(obj)  # kevin不能被追加  # ['jason']