1.面向对象的三大特征
2.封装
class Student:
def __init__(self, name, age):
self.name = name
self.__age = age #不希望在外部访问 加__
def eat(self):
print(self.name + '在吃饭')
#创建对象1
stu1 = Student('张三', 20)
stu1.eat()
print(stu1.name)
#print(stu1.age) 类属性加了 __ 不能访问
print(stu1._Student__age) #通过这样的方法也能访问 封装好像没用了 哈哈哈
3.继承
1.多重继承
class Person(object): #Person继承object类
def __init__(self,name,age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person):
def __init__(self,name,age,stu_no):
super().__init__(name,age) #调用父类的__init__函数
self.stu_no = stu_no
class Teacher(Person):
def __init__(self,name,age,teachofyear):
super().__init__(name,age)
self.teachofyear = teachofyear
stu = Student('张三',20,1)
stu.info()
teacher = Teacher('李四',23,20)
teacher.info()
'''
运行结果:
张三 20
李四 23
info
2.多继承
class A(object):
def __init__(self):
pass
class B(object):
def __init__(self):
pass
class C(A,B):
def __init__(self):
pass
3.继承中的方法重写
class Person(object): #Person继承object类
def __init__(self,name,age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person):
def __init__(self,name,age,stu_no):
super().__init__(name,age) #调用父类的__init__函数
self.stu_no = stu_no
def info(self): #Student类重写Person类info
super().info() #调用父类的info
print(self.stu_no)
class Teacher(Person):
def __init__(self,name,age,teachofyear):
super().__init__(name,age)
self.teachofyear = teachofyear
def info(self): #Teacher类重写Person类info
super().info() # 调用父类的info
print(self.teachofyear)
stu = Student('张三',20,1)
stu.info()
teacher = Teacher('李四',23,20)
teacher.info()
'''
张三 20
1
李四 23
20
'''
4.object类
class Student: #默认继承object类
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self): #重写object类的 __str__
super().__str__() #调用父类的__str__
return '我的名字是{0},今天{1}岁'.format(self.name,self.age)
stu = Student('张三',12)
print(dir(stu)) #打印属性与方法
print(stu)
print(type(stu))
5.多态
class Animal(object):
def eat(self):
print('动物会吃....')
class Dog(Animal):
def eat(self):
print("狗吃肉...")
class Cat(Animal):
def eat(self):
print("猫吃鱼")
class Person(object):
def eat(self):
print('人吃饭')
def fun(num):
num.eat()
fun(Animal())
fun(Dog())
fun(Cat())
print('-----------------------')
fun(Person())
'''
动物会吃....
狗吃肉...
猫吃鱼
-----------------------
人吃饭
'''
总结:每个对象都会调用它自己的eat 和其它编程语言(静态语言)是不一样的叫做鸭子类型
python是动态语言。
6.特殊的属性与方法
1.特殊属性
class A:
pass
class B:
pass
class C(A,B):
def __init__(self,name,age):
self.name = name
self.age = age
X = C('张三',20)
print(X.__dict__) #实例对象的属性与方法
print(C.__dict__) #类对象的属性与方法
print(X.__class__) #输出对象所属的类
print(C.__bases__) #输出父类类型的元素
print(C.__base__)#输出第一个父类类型的元素
print(C.__mro__) #输出类的 层次结构
print(A.__subclasses__()) #A的子类
'''
{'name': '张三', 'age': 20}
{'__module__': '__main__', '__init__': <function C.__init__ at 0x0000021CF3074730>, '__doc__': None}
<class '__main__.C'>
(<class '__main__.A'>, <class '__main__.B'>)
<class '__main__.A'>
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
[<class '__main__.C'>]
'''
2.特殊方法
1.__add__ 与 __len__
stu1 = Student('张三1111')
stu2 = Student('李四')
print(' __add__')
#print(stu1 +stu2) #类类型相加是会报错的 需要重写__add__才行
print(stu1 +stu2)
print(stu1.__add__(stu2))
print(' -------------------------------------------')
print(' __len__')
lst = [11,22,33,44]
print(len(lst))
print(lst.__len__())
#print(len(stu1)) #输出对象的长度 出错 要重写 __len__才行
print(len(stu1))
print(len(stu2))
'''25
__add__
张三1111李四
张三1111李四
-------------------------------------------
__len__
4
4
6
2
'''
2.__new__与__init__
class Person:
def __new__(cls, *args, **kwargs):
print('__new__被调用执行了,cls的id值为{0}'.format(id(cls)))
obj = super().__new__(cls) #所创建的对象
print('创建的对象的id为:{0}'.format(id(obj)))
return obj
def __init__(self,name,age):
print('__init__被调用了,self的id值为:{0}'.format(id(self)))
self.name = name
self.age = age
print('object这个类对象的id为:{0}'.format(id(object)))
print('Person这个类对象的id为:{0}'.format(id(Person)))
#创建实例对象
p = Person('张三',20)
print('p这个Person类的实例对象的id{0}'.format(id(p)))
'''
object这个类对象的id为:140712717295296
Person这个类对象的id为:2075319966152
__new__被调用执行了,cls的id值为2075319966152
创建的对象的id为:2075327107312
__init__被调用了,self的id值为:2075327107312
p这个Person类的实例对象的id2075327107312
'''
总结:创建实例对象是先调用__new__在调用__init__
在实例化对象:1.调用__new__把Person传给cls. 2.在object里创建对象obj.3.接着在调用__init__把obj给了self. 4. 初始化完后给了p1。
7.类的浅拷贝与深拷贝
1.变量的赋值操作
class Disk:
pass
class CPU:
pass
class Computer:
def __init__(self,cpu,disk):
self.cpu = cpu
self.disk = disk
#实例对象的赋值
cpu1 = CPU()
cpu2 = cpu1
print(id(cpu1))
print(id(cpu2))
'''
2278237566512
2278237566512
'''
2.浅拷贝
class Disk:
pass
class CPU:
pass
class Computer:
def __init__(self,cpu,disk):
self.cpu = cpu
self.disk = disk
#实例对象的赋值
cpu1 = CPU()
cpu2 = cpu1
print(id(cpu1))
print(id(cpu2))
print('-----------------------------------')
disk = Disk() #创建一个硬盘类的对象
computer = Computer(cpu1,disk) #创建计算机类
#浅拷贝
import copy
print(disk)
computer2 = copy.copy(computer)
print(computer,computer.cpu,computer.disk)
print(computer2,computer2.cpu,computer2.disk)
'''
2340005639616
2340005639616
-----------------------------------
<__main__.Disk object at 0x00000220D3347668>
<__main__.Computer object at 0x00000220D3347630> <__main__.CPU object at 0x00000220D33475C0> <__main__.Disk object at 0x00000220D3347668>
<__main__.Computer object at 0x00000220D3347710> <__main__.CPU object at 0x00000220D33475C0> <__main__.Disk object at 0x00000220D3347668>
'''
3.深拷贝
class Disk:
pass
class CPU:
pass
class Computer:
def __init__(self,cpu,disk):
self.cpu = cpu
self.disk = disk
#实例对象的赋值
cpu1 = CPU()
cpu2 = cpu1
print(id(cpu1))
print(id(cpu2))
print('-----------------------------------')
disk = Disk() #创建一个硬盘类的对象
computer = Computer(cpu1,disk) #创建计算机类
#深拷贝
import copy
print(disk)
computer3 = copy.deepcopy(computer ) # 深拷贝copy.deepcopy
print(computer, computer.cpu,computer.disk)
print(computer3, computer.cpu,computer3.disk)
'''
176978880
1721176978880
-----------------------------------
<__main__.Disk object at 0x00000190BE247668>
<__main__.Computer object at 0x00000190BE247630> <__main__.CPU object at 0x00000190BE2475C0> <__main__.Disk object at 0x00000190BE247668>
<__main__.Computer object at 0x00000190BE2476D8> <__main__.CPU object at 0x00000190BE2475C0> <__main__.Disk object at 0x00000190BE26FC88>
'''