python是面向对象语言,面向对象三大特点:封装、继承、多态
面向对象:便于代码管理,方便迭代更新。
继承了python内置类的称为新式类,否则是经典类
python3类:新式类python3中所有的类默认继承object(基类),所以一般的类都是新式类
python2类:必须显示声明继承内置类才是新式类,否则是经典类
两个类之间的区别:继承顺序的不同
程序员:看做是造物主
类:具有相同属性和方法的对象的集合
对象(实例) :实实在在的例子,某一个类实例化之后的结构体
属性:对象的描述信息,静态数据
方法:能做什么
class User():
# 类属性(公共属性)
school="sctl"
money=5000
#构造方法(个性化属性)
def __init__(self,name,age,address,password):
# 实例属性
self.name = name
self.age = age
self.address = address
self.password = password
self.money = 900
# 实例化对象
user1 = User("张三","20","长沙", "123456")
user2 = User("李四","30","武汉", "abcd")
1、先在当前实例空间查找属性和方法,找到即刻返回
2、没找到,通过类对象指针,去类空间查找
3、类空间没有,就去父类查找
user1.name = "wangwu"
print(user1.name)
#将user1实例空间中添加了一个school属性,就不会像user2去类空间中找了
user1.school = "cssc"
print(user1.school,user2.school)
手动创建实例
1、调用object的new方法,创建一个实例
2、调用init方法初始化一个实例
三种方法:
静态方法、实例方法、类方法
class User():
school="sctl"
money=5000
#构造方法
def __init__(self,name,age,address,password):
self.name = name
self.age = age
self.address = address
self.password = password
self.money = 900
#实例方法
def chongzhi(self, amount):
self.money += amount
print(f"充值了{amount},余额为{self.money}")
#类方法
# classmethod 内置装饰器
@classmethod
def chongzhi1(cls, amount):
cls.money += amount
print(f"充值了{amount},余额为{cls.money}")
# 静态方法
@staticmethod
def chongzhi2(amount):
User.money += amount
print(f"充值了{amount},余额为{User.money}")
user3 = object.__new__(User)
User.__init__(user3, "luobozi",18,"cs","12345")
user3.chongzhi(632)
user3.chongzhi1(500)
user3.chongzhi2(600)
继承的作用:实现代码复用
class Animal:
def __init__(self):
self.species="dog"
self.count=1
def eat(self):
print("i can eat")
def breath(self):
print("i can breath")
class Cat(Animal): #继承Animal类
pass
c1=Cat()
# 记住创建实例的步骤
#1.调用父类(object)的new方法创建实例
#2.再去找init构造函数,但是Cat没有构造函数,所以去找父类的构造函数执行,得到了species的值
#这里不是获取了父类的属性,而是自己没有init,而去寻找了父类,执行了父类的init
print(c1.species)
既然这样那我们在Cat子类中创建构造函数,那么创建实例的时候就不会去找父类的init了
自然我们也就没有了species
属性,那么我们想要使用父类的属性怎么办?
可以在子类的init中写super实现继承父类的方法和属性
class Animal:
def __init__(self):
self.species="dog"
self.count=1
def eat(self):
print("i can eat")
def breath(self):
print("i can breath")
class Cat(Animal): #继承Animal类
def __init__(self,name): #重写init函数
self.name= name
super().eat() #super 是子类去访问父类的方法
super().__init__() #继承父类的init中的属性
c1=Cat("小猫")
#创建Cat的init函数后,它将不会去寻找父类的init函数了
print(c1.name)
#但是我们也想继承父类init中的属性,又想有自己的init函数怎么办?
print(c1.species) # 通过super获取父类的属性
通过继承创建一个属于我们的字典类型
#自定义一个字典,添加一个排序功能
class Mydict(dict):
def sort(self):
return dict(sorted(self.items(),key=lambda x:x[1],reverse=True))
d1=Mydict()
d1["x"]=1
d1["y"]=14
d1["z"]=12
print(d1.sort())
print(type(d1))
#isinstance判断d1是否为对应的类型 返回bool类型的值
print(isinstance(d1,Mydict))
print(isinstance(d1,dict))
python原生支持多态,动态类型语言,不需要额外的实现
python崇尚鸭子类型,一直鸟走起来像鸭子,游泳起来像鸭子,那么它就是鸭子
不关心对象的具体类型,只关心有没有对应的行为
class ZFB():
def Pay(self):
pass
class WX():
def Pay(self):
pass
def payFunc(payobj):
#这就是只关心有没有这个行为,不管它是不是zfb、wx、yhk,只要有这个方法就可以了。
#(其它语言一般需要指定类型,比如在这些子类基础上再创建一个pay的父类,设置类型为pay,实现多态)
payobj.pay()
python中的私有属性是伪私有,其实就是给私有属性改名了!
class A:
def __init__(self,name):
self.name=name
self.__age=20
def show(self):
print("self.__age:",self.__age) #只有函数内部可以调用
a1=A("luobozi")
print(a1.name)
#print(a1.__age) #报错,因为是私有属性
a1.show()
#python中的私有属性是伪私有,其实就是给私有属性改名了!
print(a1.__dict__)
#{'name': 'luobozi', '_A__age': 20}
print(a1._A__age)
在类中定义,由双下划线开头双下划线结尾,并且不需要显示调用,某种场合自动执行的方法。
魔术方法都是有特殊含义的
__lt__
遇到小于号执行的方法
__init__
创建完实例后执行的方法
__new__
创建实例调用的方法
print( dir(object) ) # 查看常见的魔术方法
class A:
def __init__(self, name , age, count):
self.name = name
self.age = age
self.count = count
def __lt__(self, other): #遇到 小于号执行的 魔术方法lt,自动将表达式的第二个参数传递到other
return abs(self.count) < abs(other.count)
a1 = A("zhangsan", 20, 5)
a2 = A("lisi", 18, -8)
if a1 < a2:
print("a1小于a2")
定义接口规范,类不能实例化,规定子类必须实现父类的抽象方法,强制规范子类行为的机制
from abc import ABC, abstractmethod
class GameCharacter(ABC): #继承ABC都是抽象基类
@abstractmethod
def attack(self):
"""必须实现的攻击方法"""
pass
@abstractmethod
def defend(self):
"""必须实现的防御方法"""
pass
def blood(self):
pass
class WZJ(GameCharacter):
def attack(self):
print("attack")
def defend(self):
print("defend")
w1 = WZJ() #如果WZJ不实现attack、defend这两个方法就会报错!
先有鸡还是现有蛋啊!!!!
type – 元类 创建类的类
object – 继承 所有类的父类
#obj = type(obj)
class A:
pass
print( type(A) )