python 第四章面向对象

文章目录

      • 1.类和对象的关系
        • 1.1.对象构建小例子
      • 2.常用内置方法
        • 2.1 \_\_str__ 方法
          • 应用场景:当一个类的对象要以字符串的形式使用时要用到此方法;
          • 举例:复数类
        • 2.2 比较运算内置方法
          • 应用场景:比较某个类两个对象的某种属性大小,返回逻辑真和逻辑假
          • 举例:比较两个人成绩大小
      • 3 多态前置知识:鸭子类型
        • 命名的来由:
        • 鸭子类型举例:
      • 4.super方法、单继承与多继承、方法重写
        • 概述
        • 实例:
      • 5.type函数,issubclass函数和isinstance函数
        • 简介:
        • 小例子:
      • 6.类方法与静态方法
        • 简介:
        • 实例:类方法和静态方法实现复数加法
      • 7.动态扩展类和__slots__用法
        • 简介:
        • 绑定新方法例子
        • 绑定新属性例子
      • 8.\_\_del__ 方法和引用计数
        • 简介:

1.类和对象的关系

类和对象的关系就像数据结构和数据的关系一样,类规定了存储什么数据,对象用来实际存储数据

1.1.对象构建小例子

"""
1.类的定义和构造
2.类的方法(函数) 构造 析构
一般函数的第一个参数是实例对象名,代之需要调用函数的对象,传参时不传入
3.类的属性(成员) 公有 私有
"""

"""
python 不存在无法访问的私有属性
如何保持封装的封闭性
"""

class student:
    
    __age=0#私有成员
    
    name=""#公有成员
    Id=""
    
    def __init__(self,name,age,Id):#构造函数
        self.name=name
        self.Id=Id
        self.__age=age
        print("%s同学的信息构造完成"%self.name)
        
    def __del__(self):#析构函数
        print("%s同学的信息被删除"%self.name)
        
    def printf(self):#查看信息
        print("%s同学的年龄为:%s\n学号为:%s"%(self.name,self.__age,self.Id))
        
        
        
if __name__ == '__main__':
    #信息构造
    stu1=student("李华","21","20212203")
    stu2=student("李明","20","20212204")
    stu3=student("李强","21","20212201")
    
    #信息查看
    stu1.printf()
    stu2.printf()
    stu3.printf()
    
    #在类外调用私有成员要加类名限制(私有成员在类外也是可以定义的)
    print("%s同学的年龄为:%s"%(stu1.name,stu1._student__age))
    
    #信息删除
    stu4=stu1
    
    del stu1#对象信息备份在stu4
    del stu2
    del stu3
    

2.常用内置方法

2.1 __str__ 方法

应用场景:当一个类的对象要以字符串的形式使用时要用到此方法;
举例:复数类

"""
这里的复数对象要当作字符串输出,定义__str__方法实现
"""

class complex:
    def __init__(self,real,image):
        self.real=real
        self.image=image
    
    
    def __str__(self):
        if self.image >=0:
            return str(self.real)+'+'+str(self.image)+'i'
        else:
            return str(self.real)+str(self.image)+'i'
    
    '''
    def __str__(self):
        if self.image >= 0:
            return '{}+{}i'.format(self.real,self.image)
        else:
            return '{}{}i'.format(self.real,self.image)
    '''
c=complex(-1,2.3)
print(c)
c1=c=complex(1,-2.3)
print(c1)

2.2 比较运算内置方法

应用场景:比较某个类两个对象的某种属性大小,返回逻辑真和逻辑假

python 第四章面向对象_第1张图片

举例:比较两个人成绩大小
"""
定义一个学生类,判断一个同学的成绩是否大于另一个
感觉有点类似于C++运算符重载
"""

class student:
    def __init__(self,name,score):
        self.score=score
        self.name=name
        
    def __gt__(self,other):
        return self.score>=other.score
    
stu1=student('李华',78)
stu2=student('李明',80)
print('李明的成绩高于李华:',stu2.score>stu1.score)

3 多态前置知识:鸭子类型

命名的来由:

“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
在鸭子类型中,关注点在于对象的行为,能作什么;而不是关注对象所属的类型。
鸭子类型使得有相同功能的不同类也能实现多态,这是C++不具备的

鸭子类型举例:

"""
在鸭子类型中,关注点在于对象的行为,能作什么;
而不是关注对象所属的类型。
"""
class person:
    
    def __init__(self,name,age):
        self.name=name
        self.age=age
        
    def printt(self):
        print('%s的年龄为%d'%(self.name,self.age))
        

class Dog:
    def __init__(self,name,weight):
        self.name=name
        self.weight=weight
    def printt(self):
        print('狗狗%s的体重为%d'%(self.name,self.weight))    

def printt(tmp):
    tmp.printt()


c1=person('李华',12)
c2=Dog('乔治', 100)
printt(c1)
printt(c2) 

4.super方法、单继承与多继承、方法重写

概述

1.单继承与多继承
2.方法重写: 方法重写就是在继承中子类对于父类已有的功能进行重写,可以通过鸭子类型实现多态
3.super: 获取当前类父类的代理对象(一般用于子类构造函数对父类元素赋值)

实例:

"""
1.单继承与多继承
2.方法重写: 方法重写就是在继承中子类对于父类已有的功能进行重写,可以通过父类的引用实现多态
3.super:  获取当前类父类的代理对象(一般用于子类构造函数对父类元素赋值)


        学生
人——>           ——> 助教
        老师
        
        
"""




class person:
    
    def __init__(self,sex,name):
        self.sex=sex;
        self.name=name
        
    def Printinfo(self):
        print('{}的性别为{}'.format(self.name,self.sex))
        
class student(person):
    def __init__(self,sex,name,sno):
        super().__init__(sex,name)
        self.sno=sno
        
    def Printinfo(self):
        print('{}的性别为{},学号为{}'.format(self.name,self.sex,self.sno))
        
class teacher(person):
    def __init__(self,sex,name,tno):
        super().__init__(sex,name)
        self.tno=tno    
    
    def Printinfo(self):
        print('{}的性别为{},教师号为{}'.format(self.name,self.sex,self.tno))
        
class assistant(teacher,person):
    pass


def Printinfo(tem):
    tem.Printinfo()
    
c1=teacher('男', '李华', '11230')
c2=student('女', '李梅', '12345')
c3=person('男', '李强')
Printinfo(c1)
Printinfo(c2)
Printinfo(c3)

暂时不知python怎么消除多继承二义性,对于助教类先不扩展

5.type函数,issubclass函数和isinstance函数

简介:

1.isinstance 判断一个类是否是指定类或者是指定类的子类
2.issubclass 判断一个类是否是另一个类的子类
3.type()函数 获取一个对象所属的类

小例子:

"""
1.isinstance  判断一个类是否是指定类或者是指定类的子类
2.issubclass  判断一个类是否是另一个类的子类
3.type()函数  获取一个对象所属的类
"""

class person:
    
    def __init__(self,sex,name):
        self.sex=sex;
        self.name=name
        
class student(person):
    def __init__(self,sex,name,sno):
        super().__init__(sex,name)
        self.sno=sno

        
class flower:
    def __init__(self,colour):
        self.colour=colour
        
    
c1=person('男','李明')
c2=student('女','李华','12345')
c3=flower('red')

print(type(c1))
print(type(c2))
print(type(c3))

print('flower类是person类的子类:',issubclass(flower,person))
print('flower类是person类的子类:',issubclass(student,person))

6.类方法与静态方法

简介:

当一个属性是类所有而不是每个对象所拥有的时候要定义为类方法或静态方法,二者的区别是静态方法不用 写self,即静态方法并不绑定对象,也就无法修改对象的值

实例:类方法和静态方法实现复数加法

# -*- coding: utf-8 -*-
"""
类方法与静态方法:当类的一个方法是类所有而不是对象的方法时,可以定义为类方法或静态方法
类方法:@calssmethon               绑定了对象
静态方法:@staticmethod            未绑定对象
未绑定对象无法修改对象的值
"""

class complex:
    def __init__(self,real=0,image=0):
        self.real=real
        self.image=image
        
    @classmethod#类方法
    def add1(cls,c1,c2):
        c=complex()
        
        c2.real=3
        
        c.real=c1.real+c2.real
        c.image=c1.image+c2.image
        if c.image >=0:
            return str(c.real)+'+'+str(c.image)+'i'
        else:
            return str(c.real)+str(c.image)+'i'
        
        
        
    @staticmethod#静态方法
    def add2(c1,c2):
        c=complex()
        
        #c2.real=1 在静态方法里修改对象的值无法修改成功
        
        c.real=c1.real+c2.real
        c.image=c1.image+c2.image
        if c.image >=0:
            return str(c.real)+'+'+str(c.image)+'i'
        else:
            return str(c.real)+str(c.image)+'i'

        
c1=complex(1,2)
c2=complex(2,3)
c3=complex.add1(c1,c2)
print(c3)
c4=complex.add1(c1,c2)
print(c4)
        
    

7.动态扩展类和__slots__用法

简介:

动态扩展类:在不修改原有类的情况下动态的为类添加新的属性或方法
1.绑定新方法:需要使用 types 模块的 MethodType 方法
from types import Mythodtype
2.绑定新属性:
可以使用__slots__函数限制可绑定的新属性

绑定新方法例子

"""
动态扩展类:在不修改原有类的情况下动态的为类添加新的属性或方法
1.绑定新方法:需要使用 types 模块的 MethodType 方法
from types import Mythodtype
2.绑定新属性:
可以使用__slots__函数限制可绑定的新属性
"""
from types import MethodType 

class person:
    
    def __init__(self,sex,name):
        self.sex=sex;
        self.name=name
        
def printname(self):
    print('%s'%self.name)
    
def printsex(self):
    print('%s'%self.sex)

# 注意 __name__ 的用法
if  __name__ == '__main__':   
    person.printname=printname
    p1=person('男','李强')
    p2=person('女','李华')
    p1.printsex=MethodType(printsex,p1)
    
	#给person类绑定printname方法,给对象p1绑定printsex
    p1.printname()
    p2.printname()
    p1.printsex()
   #p2.printsex()  p2 无 printsex 这个功能

绑定新属性例子

class person:
    __slots__=('name')
        
class teacher(person):
    __slots__=('tno')

class student(person):
    pass

# 子类有限制会继承父类的限制,子类无限制不继承父类限制
if  __name__ == '__main__':   
    p1=person()
    p1.name='李华'
    
    t1=teacher()
    t1.name='李强'
    t1.tno='123'
    #t1.sno='122'  t1 不允许扩展 sno 会报错
    
    print('%s'%t1.tno)
    
    s1=student()
    s1.name='丽丽'
    s1.tno='123'
    s1.height='12'
    
    print('%s'%s1.height)
    
    # student类无限制,随意扩展

8.__del__ 方法和引用计数

简介:

使用 __del__ 方法时 , 当要释放一个对象的内存时
会先检查一个对象的引用计数,只有 count = 0 时才会释放内存

"""
使用 __del__ 方法时 , 当要释放一个对象的内存时
会先检查一个对象的引用计数,只有 count = 0 时才会释放内存

我们可以通过 sys 模块中的 getrefcount 来获取一个对象的引用计数

导致引用计数+1的情况:
1.对象被创建
2.对象被引用
3.对象作为参数被传入到一个函数中
4.对象作为元素被存储在容器中

导致引用计数-1的情况:
1.对象的别名被显式销毁
2.对象的别名被赋给了新的对象
3.一个对象离开了它的作用域(如一个函数执行完后,它里面的局部变量)
4.对象所存在的容器被销毁,或从容器中删除了对象

"""
import sys

class people:
    def __del__(self):
        print("对象已被销毁")
        
    pass

p1=people() #count = 1

count=sys.getrefcount(p1) # 对象作为参数被传到了一个函数中 count = 2
print(count)

p2=p1 #对象被引用 count = 3

count=sys.getrefcount(p1)
print(count)

del p2 #count = 1
print("-------1--------")
del p1 #count = 0
print("-------2--------")

你可能感兴趣的:(python,python,学习,开发语言)