八.面向对象基础(中)

1.析构方法和继承

析构方法

概述

当一个对象被删除或者被销毁时,python解释器也会默认调用一个方法,这个方法为__del__()方法,也称为析构方法

class Animal(object):
    def __init__(self,Name):
        self.Name = Name
        print("__init__方法被调用")
        pass
    def __del__(self):
        print("__del__方法被调用")
        print("{}对象被销毁".format(self.Name))
        pass
    pass
dog = Animal("小黑")
# 结果为打印
# __init__方法被调用
# __del__方法被调用
# 小黑对象被销毁

注:程序执行结束后才会销毁对象

class Animal(object):
    def __init__(self,Name):
        self.Name = Name
        print("__init__方法被调用")
        pass
    def __del__(self):
        print("__del__方法被调用")
        print("{}对象被删除".format(self.Name))
        pass
    pass
dog = Animal("小黑")
input("等待中...")
# 结果为打印
# __init__方法被调用
# 等待中...
# 因为程序还为执行完毕,对象不会被销毁

手动销毁对象

class Animal(object):
    def __init__(self,Name):
        self.Name = Name
        print("__init__方法被调用")
        pass
    def __del__(self):
        print("__del__方法被调用")
        print("{}对象被删除".format(self.Name))
        pass
    pass
dog = Animal("小黑")
del dog
input("等待中...")
# 结果为打印
# __init__方法被调用
# __del__方法被调用
# 小黑对象被删除
# 等待中...

析构方法总结

1、当整个程序脚本执行完毕后会自动调用__del__方法
2、当对像被手动销毁时也会自动调用__del__方法
3、析构函数一般用于资源回收,利用__del__方法销毁对象回收内存等资源

单继承

继承是面向对象的基本特征之一,继承机制允许创建分等级层次的类.继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为.

语法

class 父类
	pass
class 子类(父类)
	pass

class Animal(object):
    def Eat(self):
        print("吃")
    def Drink(self):
        print("喝")
        pass
    pass
class Dog(Animal):
    pass

Test = Dog()
Test.Eat()
# 结果为打印吃

总结:在定义子类时要继承父类,只需要类名后面的小括号()中写上父类的名字,那么父类的属性,方法,会被继承给子类.

多继承

class A(object):
    def a(self):
        print("A类")
        pass
    pass
class B(object):
    def b(self):
        print("B类")
        pass
    pass
class C(A,B):
    pass
Test = C()
Test.a()
Test.b()
# 结果为打印
# A类
# B类

多继承下类中方法同名

class A(object):
    def a(self):
        print("A类")
        pass
    pass
class B(object):
    def a(self):
        print("B类")
        pass
    pass
class C(A,B):
    pass
Test = C()
Test.a()
# 结果为打印A类
class A(object):
    def a(self):
        print("A类")
        pass
    pass
class B(object):
    def a(self):
        print("B类")
        pass
    pass
class C(B,A): 
    pass
Test = C()
Test.a()
# 结果为打印B类

因此是先后顺序,也就是继承的顺序.

拓展:
__mro__方法解析顺序

class A(object):
    def a(self):
        print("A类")
        pass
    pass
class B(object):
    def a(self):
        print("B类")
        pass
    pass
class C(B,A):
    pass
Test = C()
Test.a()
print(C.__mro__)
# 结果为打印
# B类
# (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

继承的传递

class Grandfather(object):
    def Gender(self):
        print("Male")
        pass
    pass
class Father(Grandfather):
    pass
class Son(Father):
    pass
Test = Son()
Test.Gender()
# 结果为打印Male

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

重写父类方法

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

class Grandfather(object):
    def Vocation(self):
        print("Teacher")
        pass
    pass
class Father(Grandfather):
    def Vocation(self):
        print("driver")
    pass
Test = Father()
Test.Vocation()
# 结果为driver

调用父类方法

如果在子类中有一个方法需要父类的功能,并且又要添加新的功能.如果直接重写父类方法,那么就要重复写很多代码.那么这就要调用父类方法

class Grandfather(object):
    def __init__(self,Vocation):
        self.Vocation = Vocation
        pass
    pass
class Father(Grandfather):
    def __init__(self,Vocation):
        super(Father,self).__init__(Vocation)
        self.Vocation += "Driver"
        print(self.Vocation)
    pass
Test = Father("Teacher")
# 结果为打印TeacherDriver

2.多态

作用

让具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容(功能)的函数.

所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态.

Pyhon不支持Java和C#这一类强类型语言中多态的写法,但是原生多态,Python崇尚"鸭子类型"利用python伪代码实现Java和C#的多态

鸭子类型

在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格.在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定. "鸭子测试"可以这样表述:
“当看到一只鸟走起来像鸭子,游泳起来像鸭子,叫起来也像鸭子,那么这只鸟就可以被称为鸭子.”
在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的.

class A(object):
    def Option(self):
        print("a")
        pass
    pass
class B(object):
    def Option(self):
        print("b")
        pass
    pass
class C(object):
    def Option(self):
        print("c")
        pass
    pass
def Test(obj):
    obj.Option()
    pass
a = A()
Test(a)
b = B()
Test(b)
c = C()
Test(c)
==============结果==============
a
b
c

3.类属性和实例属性

类属性的概念

类属性:就是类对象所拥有的属性,它被所有类对象的实例对象所共有,类对象和实例对象可以访问

实例属性的概念

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

class Animal(object):
    age = 15
    def __init__(self,Name):
        self.Name = Name
        pass
    pass
Test = Animal("xiaohei")
print(Animal.age)
print(Test.age)
# print(Animal.Name) # 若词句取消注释程序会产生错误
# AttributeError: type object 'Animal' has no attribute 'Name'
print(Test.Name)
============结果==============
15
15
xiaohei

类属性和实例属性的访问原理(摘抄)

类属性类对象可以访问,实例对象也可以访问,这与内存中保存的方式有关
在这里插入图片描述
上图中可以看出,所有实例对象的类对象指针指向同一类对象。实例属性在每个实例中独有一份,而类属性是所有实例对象共有一份

类属性修改与访问

如果需要在类外修改类属性,必须通过类对象去引用然后进行修改.如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性

class A(object):
    age = 15
    pass
Test = A()
print(A.age)
Test.age = 16
print(A.age)
print(Test.age)
=============结果=============
15
15
16

类方法和静态方法

类方法的概念

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

class Animal(object):
    Age = 15
    @classmethod
    def Get_Age(cls):
        print(cls.Age)
        pass
    pass
Test = Animal()
Result = Test.Get_Age() # 获取类属性
==========结果==========
15

静态方法的概念

类对象所拥有的方法,需要用@staticmethod来表示静态方法

class Animal(object):
    Age = 15
    Colour = "white"
    @classmethod
    def Get_Age(cls):
        print(cls.Age)
        pass
    @staticmethod
    def Get_Colour():
        print(Animal.Colour)

Test = Animal()
Result = Test.Get_Age()
Res = Test.Get_Colour()
==========结果==========
15
white

类方法和静态方法两者区别(摘抄)

静态方法装饰器下定义的方法属于函数(function);

类方法装饰器下定义的方法属于方法(method);

静态方法无需传入任何参数;

类方法传入的第一个参数必须是class本身cls;

静态方法与类方法一旦被调用,内存地址即确定。通过类调用和通过实例化对象调用的结果完全一样。
============================================================================
与实例方法三者区别(摘抄)

类方法的第一个参数是类对象cls,通过cls引用的类对象的属性和方法
实例方法的第一个参数是实例对象self,通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。
静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值