类:
属性+方法
属性:实例变量+类变量
实例变量:self.xxx每个实例都有自己的实例变量,互相独立,且实例之间不可以访问
类变量:一般来说是在类的方法外部声明,所有的实力均可以访问,且共享一个值。
方法:实例方法:第一个参数必须self
类方法
静态方法
1、类里面三种方法的定义
class P():
a=1 #类变量
def __init__(self):
self.b =100 #实例变量,可以跨实例方法使用
def print(self): #参数里面有self的方法,叫做实例方法
#只能被实例调用
print("实例方法被执行了!")
@classmethod
def get(cls): #方法的上面加上了装饰器:@classmethod,称之为类方法
#可以被类名调用,也可以被实例调用
#类方法的参数必须有一个,一般来说交cls,也可以不用这个名字
#类方法里面不能使用实例变量
print("类方法被执行了")
@staticmethod #静态方法:使用装饰器@staticmethod,可以没有参数
#可以用类名调用,也可以被实例调用
#静态方法里面不能使用实例变量
def get_value():
print("构造方法被执行了!")
p = P()
p.print()
P.get()
P.get_value()
print(P.a)#访问了类变量
print(p.b)#访问了实例变量
self传递的是实例的内存地址
cls传递的是类的内存地址
self和cls
都是自动传参的,不需要你人工传。
重写:子类中写了一个和基类同名的方法。
class P():
a=1 #类变量
def __init__(self):
self.b =100 #实例变量,可以跨实例方法使用
def print(self): #参数里面有self的方法,叫做实例方法
#只能被实例调用
print("实例方法被执行了!")
@classmethod
def get(cls): #方法的上面加上了装饰器:@classmethod,称之为类方法
#可以被类名调用,也可以被实例调用
#类方法的参数必须有一个,一般来说交cls,也可以不用这个名字
#类方法里面不能使用实例变量
print("类方法被执行了")
print("当前的类名:",cls.__name__)
@classmethod
def print_sth(cls):
print("又一个类方法被调用了!")
print(self.b)
@staticmethod #静态方法:使用装饰器@staticmethod,可以没有参数
#可以用类名调用,也可以被实例调用
#静态方法里面不能使用实例变量
def get_value():
print("构造方法被执行了!")
print(self.b)
P.print_sth() #我使用类名调用类方法
#第一个问题:P类有没有被实例化?------没有实例化
#第二个问题:__init__方法什么时候被执行? ----------实例化的时候执行
#第三个问题:没有实例化的情况下,self.b这个值有内容么?
class P():
a=1 #类变量
def __init__(self):
self.b =100 #实例变量,可以跨实例方法使用
def print(self): #参数里面有self的方法,叫做实例方法
#只能被实例调用
print("实例方法被执行了!")
@classmethod
def get(cls): #方法的上面加上了装饰器:@classmethod,称之为类方法
#可以被类名调用,也可以被实例调用
#类方法的参数必须有一个,一般来说交cls,也可以不用这个名字
#类方法里面不能使用实例变量
print("类方法被执行了")
print("当前的类名:",cls.__name__)
@classmethod
def print_sth(cls):
print("又一个类方法被调用了!")
#print(self.b)
@staticmethod #静态方法:使用装饰器@staticmethod,可以没有参数
#可以用类名调用,也可以被实例调用
#静态方法里面不能使用实例变量
def get_value():
print("静态方法被执行了!")
#print(self.b)
#通过类名调用类方法
#P.print_sth() #如果类方法包含实例变量,则提示self没有被定义
#第一个问题:P类有没有被实例化?------没有实例化
#第二个问题:__init__方法什么时候被执行? ----------实例化的时候执行
#第三个问题:没有实例化的情况下,self.b这个值有内容么?
#通过类名调用静态方法
P.get_value() #如果静态方法包含实例变量,则提示self没有被定义
print("**********************************************")
#可以通过实例调用类方法和静态方法么?---->可以的
pp = P()
pp.print_sth()
pp.get_value()
class P():
a=1 #类变量
def __init__(self):
self.b =100 #实例变量,可以跨实例方法使用
def print(self): #参数里面有self的方法,叫做实例方法
#只能被实例调用
print("实例方法被执行了!")
@classmethod
def get(cls): #方法的上面加上了装饰器:@classmethod,称之为类方法
#可以被类名调用,也可以被实例调用
#类方法的参数必须有一个,一般来说交cls,也可以不用这个名字
#类方法里面不能使用实例变量
print("类方法被执行了")
print("当前的类名:",cls.__name__)
@classmethod
def print_sth(cls):
print("又一个类方法被调用了!")
print(self.b)
@staticmethod #静态方法:使用装饰器@staticmethod,可以没有参数
#可以用类名调用,也可以被实例调用
#静态方法里面不能使用实例变量
def get_value():
print("静态方法被执行了!")
print(self.b)
#通过类名调用类方法
#P.print_sth() #如果类方法包含实例变量,则提示self没有被定义
#第一个问题:P类有没有被实例化?------没有实例化
#第二个问题:__init__方法什么时候被执行? ----------实例化的时候执行
#第三个问题:没有实例化的情况下,self.b这个值有内容么?
#通过类名调用静态方法
#P.get_value() #如果静态方法包含实例变量,则提示self没有被定义
print("**********************************************")
#可以通过实例调用类方法和静态方法么?---->可以的
pp = P()
pp.print_sth()
pp.get_value()
#实例调用类方法或者静态方法也不行。
#为什么有实例了,还不行么?-----------》实例方法可以用实例变量的原因是因为方法的
#第一个参数是self,这个self指向了内存的地址。
#但是,类方法和静态方法,参数中都没有self这个参数,所以这两个方法中无法找到实例的地址
#所以,依旧无法访问实例变量
2、继承
#重写
class A:
def __init__(self):
self.c =100
def print(self):
print("父类的print方法被调用了!")
class B(A): #B继承了A类
pass
b = B() #继承的好处,可以完全具备基类的所有方法和变量
b.print()
print(b.c)
基于父类的扩展(子类比基类更多的功能)
#重写
class A:
def __init__(self):
self.c =100
def print(self):
print("父类的print方法被调用了!")
class B(A): #B继承了A类
def get(self):
return 1000
b = B() #继承的好处,可以完全具备基类的所有方法和变量
b.print()
print(b.c)
print(b.get())
#重写
class A:
def __init__(self):
self.c =100
def print(self):
print("父类的print方法被调用了!")
class B(A): #B继承了A类
def get(self):
return 1000
def print(self):
print("子类的print方法被调用了!")
b = B() #继承的好处,可以完全具备基类的所有方法和变量
b.print()#此处调用的就是子类的print方法,子类中重新实现了基类的方法(重写)
print(b.c)
print(b.get())
3、多重继承
#多重继承:同时继承了多个类的方法和变量
#重写
class A:
def print1(self):
self.a =100
print("A类的print方法被调用了!")
class B:
def print2(self):
self.b=1000
print("B类的print方法被调用了!")
class C(A,B): #多重继承
def print3(self):
print("C类的print方法被调用了!")
cc = C()
cc.print1()
cc.print2()
cc.print3()
print(cc.a)
print(cc.b)
#重写
class A:
def print1(self):
self.a =100
print("A类的print方法被调用了!")
class B:
def print1(self):
self.b=1000
print("B类的print方法被调用了!")
class C(A,B): #多重继承
def print3(self):
print("C类的print方法被调用了!")
cc = C()
cc.print1() #A和B中都有print1方法,会调用谁的呢?调用的是A,因为继承的时候A在B的左边
#多重继承:同时继承了多个类的方法和变量
#重写
class A:
def print1(self):
self.a =100
print("A类的print方法被调用了!")
class B:
def print1(self):
self.b=1000
print("B类的print方法被调用了!")
class C(A,B): #多重继承
def print1(self):
A.print1(self)#可以显示的调用基类中的方法
print("C类的print方法被调用了!")
cc = C()
cc.print1() #A和B中都有print1方法,会调用谁的呢?调用的是A,因为继承的时候A在B的左边
#多重继承:同时继承了多个类的方法和变量
子类c如果做了实例化,那么从基类继承的实例变量也放到了c的地址当中,所以给A类传c的实例地址,等于是把基类实例的内容传给了A.
#重写
class A:
def __init__(self):
self.a =100
def print1(self):
print(self.a)
print("A类的print方法被调用了!")
class C(A): #多重继承
#没有实现__init__方法,则会自动调用A的__init__()方法,来对A做实例化,所以self.a也可以访问
def print1(self):
self.b=10
A.print1(self)#可以显示的调用基类中的方法,传递了c的实例地址。
print("C类的print方法被调用了!")
cc = C() #c的实例地址里面包含了self.b的内容,也包含了self.a的内容
cc.print1()
class A:
def __init__(self):
self.a =100
def __str__(self):
return "这是A类的字符串内容!"
def __repr__(self):
return "这是A类的repr字符串内容"
a = A()
print(a) #__str__方法,就是print时候(或者str函数调用)的时候,返回的字符串内容
print(str(a))