一、面向过程和面向对象两大编程思想
面向过程:功能上的封装
面向对象:属性和行为上的封装
二、类的定义
1、类:有N个对象抽取出像的属性和行为,从而归纳出来的一种类别。
自定义数据类型的语法结构:
class 类名 ():
pass
创建对象的语法格式:
对象名 = 类名()
#自定义一个类
class persion():
pass
#创建一个对象:
nana = persion() #创建了persion类下面的一个对象叫nana
2、类的组成
# haha
# time:2023/11/25 16:51
#自定义一个类
class persion():
sex = '女' # 类属性,定义在类中,方法外的变量
age = 23
#实例属性可以在整个类当中使用
#初始方法
def __init__(self,dhh,anhui): #dhh,kg 是方法的属性
self.name = dhh # =号左边是实例属性,173是
self.address = anhui
#定义在类中的函数称为方法,自带参数 self
def show(self): #实例方法
print(f"我的名字是{self.name},我的家乡是{self.address}") #实例属性可以在整个类当中使用
#静态方法
@staticmethod
def sm():
print("这是一个静态方法,不可以调用实例属性,也不可调用实例方法")
#类方法
@classmethod
def ss(cls): #cls 是 class 的简写
print("这是一个类方法,不可以调用实例属性,也不可以调用实例方法")
#创建一个对象:
nana = persion('nana','fuyang') #创建了persion类下面的一个对象叫nana, __init__ 方法中有两个形参
nana.show()
#实例方法,使用对象名进行调用
nana.show()
#实例属性,使用对象名进行调用
print(nana.name,nana.address)
#类属性,使用类名去进行调用
print(persion.age,persion.sex)
#类方法,使用类名进行调用
persion.ss()
#静态方法,使用类名调用
persion.sm()
三、对象的创建
#编写学生类,并且创建4个学生对象
class student():
school = '上海理工大学'
def __init__(self,number,name):
self.number = number
self.name = name
def show(self):
print(f"学生名字:{self.name},学号:{self.number}")
nana = student(232280531,'方雪娜')
daihan = student(232280530,'戴晗')
print(student.school)
nana.show()
daihan.show()
#将学生对象存储到列表当中去
lis = [nana,daihan]
for item in lis: #item 是lis列表的元素,列表里面的元素是student的对象,item则是student的对象
item.show() #对象名调用实例方法
四、属性和方法的调用
动态绑定属性和方法
#动态绑定属性的方法
daihan.sex = '男'
print(daihan.name,daihan.number,daihan.sex) #sex 是类中没有的属性,单独创建的独属于daihan对象的属性
# 戴晗 232280530 男
#动态绑定方法
def introduction():
print("大家好,很高兴认识大家")
daihan.intro = introduction #函数的赋值,不能加小括号,加小括号就是调用
#现在intro就是daihan对象的实例方法
daihan.intro() #调用
五、面向对象的三大特征
- 权限控制:通过对属性或方法添加单下划线,双下划线以及首尾双下划线来实现
- 单下划线:表示受保护的成员,仅仅内部使用,允许类本身和子类进行访问,实际上可以被外部代码访问
- 双下划线:表示私有成员,只允许定义该属性或方法的类本身进行访问
- 首尾双下划线:表示特殊方法
class teacher():
school = '上海理工大学'
def __init__(self,name,number,sex):
self.__name = name # 表示私有的,只能类本身去访问
self._number = number #是受保护的,只能本类和子类进行访问
self.sex = sex # 普通实例属性,类的内部,外部和子类都能访问
def _fun(self): #受保护的
print("受保护的,只能本类和子类去访问")
def __fun2(self):
print("只能定义的类可以访问")
def fun3(self):
self._fun() # 类本身访问受保护的方法
self.__fun2() # 类本身访问
print(self.__name) # 私有的实例属性
print(self._number) # 受保护的实例属性
tea1 = teacher('hahan',232280530,'boy')
print(tea1._number) #访问受保护的实例属性
# print(tea1.__name) #访问私有的实例属性,报错,在类外面就显示没有定义
#访问受保护的实例方法
tea1._fun()
#访问私有的实例方法
#tea1.__fun2() ,显示报错,出了类之外就不能调用
print(tea1._teacher__name) #访问私有的实例属性,可以直接访问
print("-"*30)
tea1._teacher__fun2() #访问私有的实例方法,可以直接访问
print("-"*30)
tea1.fun3()
print("-"*30)
print(dir(tea1)) #库函数显示tea1这个对象所有可以访问的私有属性,私有方法,实例属性,方法,受保护的属性和方法
1、属性的设置
self.__name = name # 表示私有的,只能类本身去访问
#使用@property 修改方法,将方法变为属性使用
@property
def name(self):
return self.__name
#将name属性设置为可写属性
@name.setter
def name(self,value):
self.__name = value
print(tea1.name) #调用私有属性转成的方法,直接调用方法
tea1.name = 'nanann' #可以直接修改私有的实例属性
print(tea1.name)
2、继承
介绍:在py中一个子类可以继承多个父类,一个父类也可以拥有多个子类。如果一个类没有继承任何类,这个类默认继承的是Object类
继承的语法结构:
class 类名(父类1,父类2,父类3…….):
pass
#leaders继承 了persion类
class leaders(persion):
def __init__(self,name,address,age):
super().__init__(name,address) #子类调用父类的方法
self.age = age
#docter 继承了 父类 persion
class docters (persion):
def __init__(self,name,address,department):
super().__init__(name,address) #子类调用父类的方法
self.department = department
ceo = leaders('老丁','安徽',45)
wang = docters('老刘','上海','外科')
ceo.show() #子类调用父类共有的方法
wang.show()
多继承
class Mother():
def __init__(self,age):
self.age = age
def showB(self):
print("这是父类母亲")
class Son(Father,Mother):
def __init__ (self,name,age,sex):
Father.__init__(self,name)
Mother.__init__(self,age)
self.sex = sex
son = Son('hahah',23,'girl') #调用父类中的__init__方法
son.showA()
son.showB()
3、方法重写
1、子类继承了父类就拥有了父类共有成员和受保护的对象
2、父类的方法并不能完全适合子类的需要,此时子类就可以重写父类的方法
3、子类在重写父类的方法时,要求方法的名称必须与父类方法名称相同时,在子类重写后的方法中可以通过super().xxxx()调用父类中的方法
#单继承
#leaders继承 了persion类
class leaders(persion):
def __init__(self,name,address,age):
super().__init__(name,address) #子类调用父类的方法
self.age = age
def show(self): #重写的方法名称要和父类中的方法名称一致
super().show() #调用父类的show方法
print(f'我的年龄是{self.age}')
#docter 继承了 父类 persion
class docters (persion):
def __init__(self,name,address,department):
super().__init__(name,address) #子类调用父类的方法
self.department = department
def show(self): #重写的方法名称要和父类中的方法名称一致
#super().show() 不使用父类的方法,全部重写
print(f"大家好,我的名字是{self.name},我来自{self.address},我的科室是{self.department}")
ceo = leaders('老丁','安徽',45)
wang = docters('老刘','上海','外科')
ceo.show() #调用子类自己的show方法
wang.show()
六、动态语言的特点
多态
多态:多种形态,即便不知道一个变量所引用的对象到底是什么类型,任然可以通过这个变量调用对象的方法。在程序运行过程中根据变量所引用对象的数据类型,动态决定调用哪个对象中的方法。Py语言中的多态,不关心对象的数据类型,壹基金是否存在继承关系,只关心对象的行为。只要不同的类中有同名的方法,就可以实现多态
#多态
class Dog():
def eat(self):
print("狗喜欢吃骨头")
class Cat():
def eat(self):
print("猫喜欢吃鱼")
class Fish():
def eat(self):
print("大鱼吃小鱼,小鱼吃虾米")
#对于以上三个类,无任何关系,但是都有一个同名的方法 eat
def funn(obj): #obj 是函数的形式参数,不知此时这个形参的数据类型,只有当程序运行时候才知道对象的数据类型
obj.eat() #通过 Obj 对象去调用 eat方法
dog = Dog()
cat = Cat()
fish = Fish()
#调用funn 函数
funn(dog) #Py 中的多态,不关心对象的数据类型,只关心对象是否具有同名的方法
funn(cat)
funn(fish)
# 狗喜欢吃骨头
# 猫喜欢吃鱼
# 大鱼吃小鱼,小鱼吃虾米
七、Object类的常用方法
1、Object类
所有类直接或间接的父类
所有类都拥有Object类的属性和方法
print(dog) #直接输入对象名,调用的是str方法:__str__ 可以在子类中重写str方法
2、特殊方法
3、特殊属性
4、类的深拷贝与浅拷贝
5、变量的赋值---只是形式上的两个变量,实际上还是指向同一个对象
#类的深拷贝与浅拷贝
class Cpu():
pass
class Disk():
pass
class Computer():
def __init__(self,cpu,disk):
self.cpu = cpu
self.disk = disk
cpu = Cpu()
disk = Disk()
computer = Computer(cpu,disk)
#变量的赋值
com1 = computer
print(computer) #两者的内存地址都是相等的,
print(com1) # 对象的赋值指向的是同一个对象,对象的实例属性值得也是同一个实例属性
# <__main__.Computer object at 0x1027e3990>
# <__main__.Computer object at 0x1027e3990>
6、类对象的浅拷贝
#类对象的浅拷贝
import copy
com2 = copy.copy(computer)
print(computer) #com2是新产生的对象,子对象没变
print(com2)
# <__main__.Computer object at 0x100d379d0>
# <__main__.Computer object at 0x100d37a90>
7、类对象的深拷贝
#类对象的深拷贝
com3 = copy.deepcopy(computer)
print(computer,computer.cpu,computer.disk) #类以及类的属性都不同
print(com3,com3.cpu,com3.disk)
# <__main__.Computer object at 0x1044a3a50> <__main__.Cpu object at 0x1044a39d0> <__main__.Disk object at 0x1044a3a10>
# <__main__.Computer object at 0x1044a3a90> <__main__.Cpu object at 0x1044a3b50> <__main__.Disk object at 0x1044a3bd0>