面向对象(中)

目录

析构方法

继承

重写和调用父类的方法

多态

属性

类方法和静态方法


析构方法 

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

class Animal:
    def __init__(self,name):
        self.name=name
        print('这是构造初始化方法')
        pass
    def __del__(self):
        #主要的应用就是来操作对象的释放,一旦释放完了,对象便不能使用
        print('当在某个作用域下面,没有被使用【引用】的情况下,解释器会自动调用此函数来释放内存空间')
        print('这是析构方法')
        print('%s这个对象被彻底清理了,内存空间也释放掉了'%self.name)
    pass
cat=Animal('小花猫')
del cat#手动清理删除对象,会执行del函数

# print('*'*40)
# dog=Animal('柯基小狗')

继承

在python中展现面向对象的三大特征: 封装、继承、多态
封装:指的是把内容封装到某个地方,便于后面的使用,他需要把内容封装到某个地方从另外一个地方去调用被封装的内容。
对于封装来说,其实就是使用初始化构造方法将内容封装到对象中,然后通过对象直接或者self来获取被封装的内容。

继承: 和现实生活当中的继承是一样的:也就是 子可以继承父的内容【属性和行为】(爸爸有的儿子都有,相反 儿子有的爸爸不一定有,所以对于面向对象的继承来说  其实就是将多个类共有的方法提取到父类中 子类仅需继承父类而不必一一去实现,这样就可以极大的提高效率 减少代码的重复编写,精简代码的层级结构便于拓展。

多态在下面介绍。

单继承:

class Animal:
    def eat(self):
        print('吃饭了')
        pass
    def drink(self):
        pass
    pass

class Dog(Animal): #继承Animal父类,Dog为子类
    def wwj(self):
        '''
        子类独有的
        :return:
        '''
        print('小狗汪汪叫')
    pass
class Cat(Animal):
    def mmj(self):
        print('小猫喵喵叫')
    pass
d1=Dog()
d1.eat() #具备了吃的行为
print('*********cat的行为************')
c1=Cat()
c1.eat()

 多继承:

class shenxian:
    def fly(self):
        print('神仙会飞')
        pass
    pass

class Monkey:
    def chitao(self):
        print('猴子喜欢吃桃')
        pass
    pass

class Sunwukong(shenxian,Monkey): #继承了多个类
    pass

swk=Sunwukong()
swk.fly()
swk.chitao()

当多个父类存在相同的方法时,应该调用那一个?我们举例说明

class D(object):
    def eat(self):
        print('D.eat')
        pass
    pass
class C(D):
    def eat(self):
        print('C.eat')
        pass
    pass
class B(D):
    pass
class A(B,C):
    pass

a=A()
a.eat() #C.eat 在执行eat的方法时,查找方法的顺序:A去B中若B中没有去C中查找 如果C类中没有则去D类查找,如果还没找到就会报错
print(A.__mro__)#可以显示类的依次继承关系

可以发现,在执行eat的方法时,查找方法的顺序:A去B中若B中没有去C中查找 如果C类中没有则去D类查找,如果还没找到就会报错。

间接继承:

class Grandfather:
    def eat(self):
        print('吃的方法')
        pass
    pass
class Father(Grandfather):
    # def eat(self):#因为父类中已经存在这个方法,在这里相当于方法重写【方法覆盖了】
    #     print('爸爸经常吃海鲜')
    pass
class Son(Father):
    pass

son=Son()
print(Son.__mro__)
son.eat()#此方法时从Grandfather继承过来的

重写和调用父类的方法

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

为什么要重写:父类的方法不满足子类的需要,那么子类就可以重写父类或者完善父类。

class Dog:
    def __init__(self,name,color):
        self.name=name
        self.color=color
        pass

    def bark(self):
        print('旺旺叫...')
        pass
    pass
class kejiquan(Dog):
    def __init__(self,name,color): #重写父类的方法
        #针对这种需求,我们就需要去调用父类的函数了
        #Dog.__init__(self,name,color) #手动调用父类的方法,执行完毕,就可以具备name和color这俩个实例属性
        super().__init__(name,color)#super是自动的找到父类进而调用方法,假设继承了多个父类,那么会按照顺序逐个的去找,然后再调用
        #扩展其他的属性
        self.height=90
        self.weight=20
        pass
    def __str__(self):
        return '%s是%s,升高是%d,体重是%d'%(self.name,self.color,self.height,self.weight)

    def bark(self): #属于重写父类的方法
        super().bark()#调用父类方法
        print('叫的跟神一样')
        print(self.name)
        pass
    pass
kj=kejiquan('柯基犬','红色')
kj.bark()
print(kj)

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

多态

多态:顾名思义就是多种状态、形态,就是同一种行为 对于不同的子类【对象】有不同的行为表现。

要想实现多态 必须的有两个前提需要遵守:
1、继承:多态必须发生在父类和子类之间
2、重写: 子类重写父类的方法

多态有什么用:
增加程序的灵活性
增加程序的拓展性

#案例演示
class Animal:
    '''
    父类
    '''
    def say_who(self):
        print('我是一个动物...')
        pass
    pass
class Duck(Animal):
    def say_who(self):
        print('我是一只鸭子')
    pass
class Dog(Animal):
    def say_who(self):
        print('我是一只小狗')
        pass
    pass
class Cat(Animal):
    def say_who(self):
        print('我是一只小猫')
        pass
    pass
class Bird(Animal):#新增鸟类
    def say_who(self):
        print('我是一个鸟')
        pass
    pass
class People():
    def say_who(self):
        print('我是人类')
        pass
    pass

class student(People):
    def say_who(self):
        print('我是一年级的张明')
        pass
    pass


def commonInvoke(obj):
    '''
    统一调用的方法
    :param obj:对象实例
    :return:
    '''
    obj.say_who()

# duck1=Duck()
# duck1.say_who()
# dog=Dog()
# dog.say_who()
# cat=Cat()
# cat.say_who()

listObj=[Duck(),Dog(),Cat(),Bird(),student()]
for itme in listObj:
    '''
    循环调用函数
    '''
    commonInvoke(itme)

类方法和静态方法 

属性:类属性和实例属性

类属性就是类对象所拥有的属性

class Student:
    name='李明' #属于类属性,就是student类对象所拥有的
    def __init__(self,age):
        self.age=age #实例属性
        pass
    pass
Student.name='李易峰'#通过类对象修改数据,因为name的所有权属于类对象
lm=Student(18)
print(lm.name) #通过实例对象去访问类属性
print(lm.age)
print('-----------xh数据-----------------------')
xh=Student(28)
print(xh.name)
print(xh.age)
print('--------------通过类对象访问name------------')
print(Student.name) #类名.属性名去访问

通过上述,可以发现

1.类属性是可以被类对象和实例对象共同访问使用的

2.实例属性只能由实例对象访问

3.通过实例对象没法修改类属性

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

类对象所拥有的方法,需要用@staticmethod来表示静态方法,静态方法不需要任何参数。

class People:
    country='china'
    @classmethod #类方法需要用classmethod来进行修饰
    def get_country(cls):
        return cls.country #访问类属性
        pass
    @classmethod
    def change_country(cls,data):
        cls.country=data #在类方法中修改类属性的值
        pass
    @staticmethod #静态方法 不需要传入参数
    def getData():
        return People.country #通过类对象去引用

    @staticmethod
    def add(x,y):
        return x+y
    pass

print(People.get_country()) #通过类对象去引用
p=People()
print(p.get_country())#实例对象访问
print('修改之后的数据')
People.change_country('英国')
print(People.get_country())
print(People.add(10,56)) #带参数的静态方法

一般情况下,我们不会通过实例对象去访问静态方法。

为什么要使用静态方法呢

1.由于静态方法注意来存放逻辑性代码,本身和类以及实例对象没有交互,也就是说,在静态方法中,不会设计到类中属性和方法的操作

2.数据资源能够得到有效的充分利用

import time #引入时间模块
class Timetest:
    def __init__(self,hour,min,second):
        self.hour=hour
        self.min=min
        self.second=second
    @staticmethod
    def showTime():
        return time.strftime("%H:%M:%S",time.localtime())
    pass
print(Timetest.showTime())
t=Timetest(2,10,22)
print(t.showTime()) #没有必要通过这种方法访问静态方法

从方法定义的形式可以看出来
1.类方法的第一个参数是类对象 cls 进而去引用类对象的属性和方法  必须用装饰器 @classmethod来修饰
2.实例方法的第一个参数必须是self,通过这个self 可以去引用类属性或者实例属性,若存在相同名称实例属性和类属性的话,实例属性的优先级最高
3.静态方法不需要定义额外的参数,若是要引用属性的话 则可以通过类对象或者是实例对象去引用即可   必须用装饰器 @staticmethod来修饰

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值