Python学习笔记(新手入门)(7)面向对象

本文介绍了Python中的面向对象编程特性,包括析构方法、继承(单继承、多继承、继承传递)、父类方法(重写与调用)以及多态的概念和应用。重点讲解了继承的深度优先和广度优先查找策略,以及类属性、实例属性、类方法和静态方法的使用。
摘要由CSDN通过智能技术生成

目录

3.8.4 析构方法

3.8.5 继承

3.8.5.1 单继承

3.8.5.2 多继承

3.8.5.3 继承的传递

3.8.6 父类方法

3.8.6.1 重写和调用父类方法

3.8.7 多态

3.8.7.1 类属性和实例属性

3.8.7.2 类方法和静态方法


3.8.4 析构方法

  • 当整个程序脚本执行完毕后自动调用__del__方法

  • 当对象被手动销毁时也会自动调用__del__

  • 析构函数一般用于资源回收,利用__del__方法销毁对象回收内存等资源

class Animals:
     def __init__(self,name):
         self.name = name
         print("__init__构造初始化方法")
         pass
     def __del__(self):
         print("这是析构方法")
         print("当某个作用域下面,没有被使用引用的情况下,解析器会自动调用此函数")
     pass
 ​
 Cat = Animals("Rany")

3.8.5 继承

  • 面向对象三大特征:封装、继承、多态

  • 封装:是指把内容封装到某个地方,从另外一个地方去调用被封装的内容,以便于后面的使用。

  • 继承:子类可以继承父类的属性和行为

3.8.5.1 单继承

对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需要继承父类而不必一一实现每个方法。

方法:class 子类(父类):

class Anmials:
     def eat(self):
         print("吃饭")
         pass
     def drink(self):
         print("喝水")
         pass
     pass
 class dog(Anmials): #继承Anmials,dog是Anmials的子类
     def wwj(self):
         print("汪汪叫")
         pass
     pass
 # dog中一共有三个方法,继承自父类的eat、drink和自己wwj。
 dog1 = dog()
 dog1.eat()
 dog1.drink()
 dog1.wwj()

3.8.5.2 多继承

  • 多继承就是使用一个子类去继承多个父类的方法

  • 在Python3以上版本按照广度优先原则来进行查找

class A: #新建父类A
     def eat(self):
         print("A")
         pass
     pass
 class B: #新建父类B
     def drink(self):
         print("B")
         pass
     pass
 class C: #新建父类C
     def run(self):
         print("C")
         pass
     pass
 class ABC(A,B,C): #使用ABC继承三个父类
     pass
 abc = ABC() #创建实例
 abc.eat() #实例化对象
 abc.drink()
 abc.run()

3.8.5.3 继承的传递

类的传递过程中,我们把父类称为基类,子类称为派生类,父类的属性和方法可以一级一级的传递到子类。

 class A:
     def foo(self):
         print('called A.foo()')
 ​
 class B(A):
     pass
 ​
 class C(A):
     def foo(self):
         print('called C.foo()')
 ​
 class D(B, C): 
     pass
 ​
 if __name__ == '__main__':
     d = D() 
     d.foo()

B、C 是 A 的子类,D 多继承了 B、C 两个类,其中 C 重写了 A 中的 foo() 方法。如果 A 是经典类(如上代码),当调用 D 的实例的 foo() 方法时,Python 会按照深度优先的方法去搜索 foo() ,路径是 B-A-C ,执行的是 A 中的 foo() ;如果 A 是新式类,当调用 D 的实例的 foo() 方法时,Python 会按照广度优先的方法去搜索 foo() ,路径是 B-C-A ,执行的是 C 中的 foo() 。因为 D 是直接继承 C 的,从逻辑上说,执行 C 中的 foo() 更加合理,因此新式类对多继承的处理更为合乎逻辑。在 Python 3.x 中的新式类貌似已经兼容了经典类,无论 A 是否继承 object 类, D 实例中的 foo() 都会执行 C 中的 foo() 。但是在 Python 2.7 中这种差异仍然存在,因此还是推荐使用新式类,要继承 object 类。

3.8.6 父类方法

3.8.6.1 重写和调用父类方法

所谓重写就是在子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法

 class A:
     def foo(self):
         print('called A.foo()')
 ​
 class C(A): #继承父类
     def foo(self): #重写父类方法
         print('called C.foo()')
         
 ranys=A() #调用父类方法
 ranys.foo()
 ​
 rany=C() #调用子类方法
 rany.foo()

3.8.7 多态

  • 所谓多态就是定义时的类型和运行时的类型不一样,此时就称为多态。不同子类的对象有不同的行为表现。

  • 实现多态的前提:

    • 必须发生在父类的子类之间

    • 重写

  • 特点

    • 只关心对象的实例方法是否同名,不关心对象所属的类型;

    • 对象所属的类之间,继承关系可有可无;

    • 多态的好处可以增加代码的外部调用灵活度,让代码更加通用,兼容性比较强;

    • 多态是调用方法的技巧,不会影响到类的内部设计。

#对象所属的类之间有继承关系(应用更广)
 class gradapa(object):
     def __init__(self, money):
         self.money = money
 ​
     def p(self):
         print("this is gradapa")
 ​
 class father(gradapa):
     def __init__(self, money, job):
         super().__init__(money)
         self.job = job
 ​
     def p(self):
         print("this is father,我重写了父类的方法")
 ​
 class mother(gradapa):
     def __init__(self, money, job):
         super().__init__(money)
         self.job = job
 ​
     def p(self):
         print("this is mother,我重写了父类的方法")
         return 100
 ​
 # 定义一个函数,函数调用类中的p()方法
 def fc(obj):
     return obj.p()
 ​
 gradapa1 = gradapa(3000)
 father1 = father(2000, "工人")
 mother1 = mother(1000, "老师")
 ​
 fc(gradapa1)  # 这里的多态性体现是向同一个函数,传递不同参数后,可以实现不同功能.
 fc(father1)
 print(fc(mother1))
 ​

3.8.7.1 类属性和实例属性

  • 类属性概念:就是了哦对象所拥有的属性,他被所有类对象的实例对象所共有,类对象和实例对象都可以访问

  • 实例属性的概念:实例属性所拥有的属性,只能通过实例对象访问

class Student:
     name = "Rany" #类属性,属于类的属性,就是Student的属性
     def __init__(self,age):
         self.age=age #实例属性
         pass
     pass
 ​
 Ran = Student(19)
 print(Ran.name) #访问类属性
 print(Ran.age) #访问实例属性
 print(Student.name) #;类属性是可以被类对象和实例对象共同访问使用的,实例属性只能由实例对象访问
 # print(Student.age) #这个不能被访问

3.8.7.2 类方法和静态方法

类方法的概念

类对象所拥有的方法,需要用装饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数,类方法可以通过类对象,实例对象调用。

 class People:
     country = "china"
     #类方法 用 classmethod
     @classmethod
     def get_country(cls):
         return cls.country #访问类属性
         pass
     pass
 print(People.get_country()) #通过类对象去引用
 p = People()
 print("实例对象访问%s"%p.get_country())

静态方法

  • 静态方法需要用到修饰器 @ staticmethod 来标识,告诉解释器这是一个静态方法

  • 通过类名调用静态方法

 #语法:
 @staticmethod
 def 静态方法名():
     pass
 #举例
 class Student:
     company = "js" #类属性
 ​
     @staticmethod
     def add(a,b): #静态方法
         print("{0}+{1}={2}".format(a,b,(a+b)))
         return a++b
     pass
 ​
 Student.add(10,20)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

英语渣i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值