第一部分:类属性
class person:
name = 'Xavier'
__num = 20156307
p = person() #生成实例对象P
print(p.name) #正确,不提倡,这样会造成类属性值不一样,
# 因为实例对象在类外可以更改属性值,eg第12行,但不影响类对象中的类属性14行
print(person.name)
person.age = 21 #通过类名在类外追加定义一个类属性,属于类对象,包括它的实例对象
p.year = 2018 #通过实例对象在类外追加定义一个实例属性,仅属于实例对象特有,不能通过类对象访问
print(person.age)
print(p.age)
p.age = 20
print(p.age)
print(person.age)
print(p.year)
#print(person.year) #错误
第二部分:实例属性
'''
实例属性是不需要在类中显示定义的,而是在__init__构造函数中定义的,
定义时以self作为前缀。在其他方法中也可以随意添加新的实例属性,但不提倡,
所有的实例属性最好放在__init__中给出。实例属性属于实例(对象),只能通过对象访问。
'''
#AttributeError(属性错误): type object 'car' has no attribute(属性) 'color'
#总结:
'''
1.类属性可以由类对象或实例对象调用,推荐类对象,修改类属性只能通过类对象修改
2.实例属性定义在构造函数__init__中,只能由实例对象调用
3.实例方法,只能实例化调用,即通过实例对象调用;
4.若要通过类对象调用类方法,则须对类方法进行装饰用:@classmethod标识。详见:类方法
'''
class car:
def __init__(self,c): #构造函数,用于定义实例属性
self.color = c #定义实例属性
def lengths(self): #定义实例方法
self.length = 1.83 #给实例对象添加属性,不提倡,因为这样使得实例对象不能直接
#调用该属性,eg第16行
s = car('red')
print(s.color)
#print(car.color) #错误,实例属性,只能通过实例对象调用,不能被类对象调用
#print(s.length) #错误,不能直接调用lengths()方法中的属性,必须通过实例方法调用,如下:
s.lengths()
print(s.length)
#car.lengths() #错误,类方法只能实例化后在调用,即只能通过实例对象调用,如下:
drive = car('bule') #实例化,形成具体实例对象,self此时表示drive对象(类似this指针)
drive.lengths() #通过实例对象调用实例方法
print(drive.length)
第三部分:类方法和实例方法
'''
类方法是类对象拥有的方法,需要用修饰器“@classmethod”来标识其为类方法
第一个参数必须是类对象,一般以cls(类方法参数)作为第一个参数,区别于self(实例方法参数)
注:
定义类时:1.若定义方法时,没有用修饰器修饰,则该方法属于“实例方法”,类外只能用实例对象调用。
2.若定义方法时,用修饰器修饰,则该方法属于“类方法”,可用类对象调用。
'''
class person:
place = 'Changsha'
@classmethod #类方法,用@classmethod来进行装饰
def getplace(cls):
return cls.place
def setplace(self,place1): #实例方法,没用修饰器装饰
self.place = place1
p = person()
print(p.getplace()) #可以通过实例对象调用类方法
print(person.getplace()) #可以通过类对象调用类方法
p.setplace('Haerbin') #这语句仅仅改变了实例对象p的实例方法setplace()中的place值,
#并未改变修饰器所创建的类方法中的place。eg如下:
#即只能改变实例,不会改变类,修饰器修饰的类方法它不会被改变
#若要改变类属性,则必须在修饰器中修改
# 或通过类对象修改类属性(person.place = 'Haerbin')。
print(p.getplace()) #输出仍为Changsha
print(p.place) #可以通过实例对象调用实例方法,输出改变为Haerbin
print(person.place) #输出仍为Changsha
#print(person.setplace()) #不可以通过类对象调用实例方法
第三部分:类继承
'''
1.在子类实例化时,创建子类实例对象不会自动调用父类构造函数:例:15,23行,必须在子类中显式调用。
2.若要在子类中调用父类方法,则需以“父类名.方法”方式调用。例:19,27行,注意要传递self参数
3.子类继承的仅是父类中所有公有属性和方法,对于私有子类无法继承,因此无法在子类中通过父类名访问。
'''
class UniversityMember: #定义父类
def __init__(self,name,age):
self.name=name
self.age=age
print('init UniversityMember:',self.name)
def tell(self):
print('name:{};age:{}'.format(self.name,self.age))
class Student(UniversityMember): #定义子类Student
def __init__(self,name,age,marks):
UniversityMember.__init__(self,name,age)
self.marks=marks
print('init Student:',self.name)
def tell(self):
UniversityMember.tell(self)
print('marks:',self.marks)
class Teacher(UniversityMember): #定义子类Teacher
def __init__(self,name,age,salary):
UniversityMember.__init__(self,name,age) #显式调用父类构造方法
self.salary=salary
print('init Teacher:',self.name)
def tell(self):
UniversityMember.tell(self) #通过父类名调用父类中的方法
print('salary:',self.salary)
s=Student('Brenden',18,92)
t=Teacher('Jasmine',28,2450)
members=[s,t] #把不同的实例对象放进列表中
for member in members:
member.tell() #调用子类实例方法
第四部分:多重继承
'''
class 子类名(父类名1,父类名2,...)
类体
若子类没有重新定义构造函数,则python3只会自动执行第一个父类的构造方法。且父类1,2有
同名的方法,则子类的实例化对象调用该函数时,调用的是第一个父类的方法。
注:
1.在python2中采用的是深度优先遍历,即下面第23行,调用foo1()方法,先搜索第一个父类B,
若没有B中没有foo1(),则继续搜索父类的父类A,所以在python2中输出为:AAAAA
2.在python3中不用该方法,而是直接先搜索B,在搜索C。所以输出:CCCCC
'''
class A():
def foo1(self):
print("AAAAA")
class B(A):
def foo2(self):
print("BBBBB")
class C(A):
def foo1(self):
print("CCCCC")
class D(B,C):
pass
d = D()
d.foo1()
————————————————
版权声明:本文为CSDN博主「算法_魔征了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/VarryTan/article/details/85632722