OOP面向对象中
析构方法
__ del __()——当对象被删除或销毁时,解释器默认调用的方法
class Animal:
def __init__(self, name): # 自动执行
self.name = name
print('__init__')
pass
def __del__(self): # 自动执行
# 释放资源
print('__del__')
pass
pass
cat = Animal('cat')
del cat # 手动删除对象
input('等待中')
dog = Animal('dog')
继承
OOP三大特征:
- 封装——把内容封装到某个地方,从另外一处调用封装内容
- 继承——子可以继承父的属性和方法
- 多态——
class 类名(父类):
‘’’
子类可继承父类公共的属性和方法
‘’’
单继承
class Animal:
def eat(self):
print('eat')
pass
def drink(self):
print('drink')
pass
pass
class Dog(Animal): # 继承Animal父类
def wwj(self):
print('汪汪叫')
pass
pass
class Cat(Animal): # 继承Animal父类
def mmj(self):
print('喵喵叫')
pass
pass
d1 = Dog()
d1.eat() # 已继承 具备吃
d1.wwj()
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() # 广度优先遍历 A-B-C-D
print(A.__mro__)
继承传递
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() # 广度优先遍历 A-B-C-D
print(A.__mro__)
重写
子类中与父类同名的方法,子类中的方法会覆盖父类
class Dog:
def __init__(self, name, color):
self.name = name
self.color = color
pass
def bark(self):
print('汪汪叫')
pass
pass
class keji(Dog):
def __init__(self, name, color): # 重写父类方法
# 调用父类方法 具备name,color两个实例属性
# Dog.__init__(self, name, color) # 手动找父类
super().__init__(name, color) # super自动找父类 继承多个父类,按顺序逐个寻找
self.height = 90
self.weight = 20
pass
def __str__(self):
return '{}的颜色{} 身高为{} 体重为{}'.format(self.name, self.color, self.height, self.weight)
def bark(self):
super().bark()#调用父类方法
print('giaogiao叫') # 重写父类的方法
print(self.name)
pass
pass
kj = keji('keji', 'red')
kj.bark()
print(kj)
多态
多态:同一种行为对不同子类有不同的行为表现
前提:
- 继承
- 重写
用处:
- 增加代码灵活性
- 增加代码拓展性
class Animal:
'''
基类
'''
def say_who(self):
print('我是动物')
pass
pass
class Duck(Animal):
'''
鸭子【派生类】
'''
def say_who(self):
'''
重写父类方法
:return:
'''
print('我是鸭子')
pass
pass
class Dog(Animal):
'''
狗【派生类】
'''
def say_who(self):
'''
重写父类方法
:return:
'''
print('我是狗')
pass
pass
class Cat(Animal):
'''
猫【派生类】
'''
def say_who(self):
'''
重写父类方法
:return:
'''
print('我是猫')
pass
pass
# duck1 = Duck()
# duck1.say_who()
#
# dog1 = Dog()
# dog1.say_who()
#
# cat1 = Cat()
# cat1.say_who()
def commonInvoke(obj):
'''
统一调用
:param obj:
:return:
'''
obj.say_who()
listObj = [Duck(), Dog(), Cat()]
for item in listObj:
'''
循环调用函数
'''
commonInvoke(item)
类属性和实例属性
类属性:类对象拥有,被所有类对象的实例对象共有,类对象和实例对象可以访问
实例属性:实例对象用有,只能通过实例对象访问
class Student:
name = '李明' # 类属性 Student类对象拥有
def __init__(self, age):
self.age = age
pass
pass
Student.name='liyifeng'#通过类对象修改 可以
lm = Student(18)
print(lm.name) # 通过实例访问类属性
lm.name='liudehua'#通过实例对象 对类属性修改 不可以
print(lm.name)
print(lm.age) # 通过实例访问实例属性
print('---------xiaohua')
xh = Student(15)
print(xh.name)
print(xh.age)
print('---------xiaohua')
print(Student.name) # 通过类对象访问类属性
# print(Student.age) # 通过类对象访问实例属性
类方法和静态方法
类方法
类方法——类对象拥有的方法,需要装饰器@classmethod来标识,第一个参数必须为类对象,一般以cls作为第一个参数,类方法可以通过类对象,实例对象调用
class People:
country = 'china'
# 类方法
@classmethod
def get_country(cls):
return cls.country # 访问类属性
pass
# 类方法
@classmethod
def change_country(cls, data):
cls.country = data # 在类方法中修改类属性的值
pass
print(People.get_country()) # 通过类对象引用
p = People()
print('实例对象访问%s' % p.get_country())
print('--------修改后')
People.change_country('jepan') # 类方法修改类属性
print(People.get_country()) # 通过类对象去引用
静态方法
静态方法——类对象拥有的方法,需要@staticmethod来标识,静态方法不需要任何参数
用处——存放逻辑性代码,本身和类以及实例对象没有交互,静态方法不会涉及类中方法和属性的操作,数据资源能够得到充分利用
class People:
country = 'china'
# 类方法
@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.add(10, 20)) # 带参数的静态方法
print(People.getData()) # 通过类对象调用静态方法
p = People()
print(p.getData()) # 一般不会 通过实例对象调用静态方法
print(People.get_country()) # 通过类对象引用
p = People()
print('实例对象访问%s' % p.get_country())
print('--------修改后')
People.change_country('jepan') # 类方法修改类属性
print(People.get_country()) # 通过类对象去引用
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
pass
print(TimeTest.showTime())
t=TimeTest(2,10,15)
print(t.showTime()) #没必要用通过实例 访问静态方法
总结
类方法的第一个参数是类对象cls进而引用类对象的属性和方法,用@classmethod来标识
实例方法的第一个参数是self,通过self引用类属性灬实例属性,若存在相同名称实例属性和类属性,实例属性优先级高
静态方法不需要定义额外参数,引用属性可通过类对象或实例对象引用,用@staticmethod来标识