1.面向对象编程:通过类来进行编写程序
面向过程:c语言,不适用类的方式
类的好处:将一个东西的状态封装到实例变量中,通过实例方法制定维护状态(实例变量和类变量)的规则,一次来实现数据的安全和一致性,减少脏数据。
class Person: #类定义,类对象:类变量和方法
COUNT=0 #类变量
def __init__(self,name,age): #构造函数(方法)
self.name=name #name是局部变量,存到实例变量中
self.age=age
Person.COUNT+=1 #对类变量进行累计
#局部变量:函数内参数,自己定义的没有self的变量,仅在函数内部有效
#实例变量:self.xxx,可以在类里面的所有方法使用
#类变量:在类中的方法外面定义,全局只有一份,使用时候是“类名.类变量名”。
# 如果此实例中没有和类变量同名的实例变量,则可以使用self.类变量名来进行读取类变量的值
def get_age(self):
return self.age
def set_age(self,age): #设定了年龄的修改规则
if isinstance(age,(int,float)) and 0<age<200:
self.age=age
@staticmethod #静态方法
def count_person():
return Person.COUNT #返回一个类变量
p1=Person("小草",3) #实例化的时候,自动调用__init__方法,将数据传入构造方法中的name
p2=Person("小花",5)
print(p1.get_age())
p1.set_age(22)
print(p1.get_age())
print("通过类名读取类变量",Person.COUNT)
print("通过实例名读取类变量",p1.COUNT)
print("通过类名调用静态方法",Person.count_person()) #通过类名调用静态方法
print("通过实例调用静态方法",p1.count_person()) #通过实例调用静态方法
#类:用过class定义的代码
#类对象:类变量和所有类中定义的方法(实例方法、静态方法、类方法)
#实例对象:实例变量和对应类所在的地址(指针)
#实例方法:定义参数一定要有self、只能实例调用。可以使用实例变量和类变量。
#类方法:@classmethod,必须有一个cls的方法参数,传类对象的内存地址。里面不能使用self.xxx的实例变量。
#可以通过类名或者实例名调用
#静态方法:@staticmethod,可以没有任何参数。里面不能使用self.xxx的实例变量。
#可以通过类名或者实例名调用
#print(id(p1))#两实例内存地址不一样
#print(id(p2))
私有变量和私有方法
class Person: #类定义,类对象:类变量和方法
COUNT=0 #类变量
__FLAG=0
def __init__(self,name,age): #构造函数(方法)
self.name=name #name是局部变量,存到实例变量中
self.__age=age
Person.COUNT+=1 #对类变量进行累计
def get_age(self):
return self.__age
def set_age(self,age): #设定了年龄的修改规则
if isinstance(age,(int,float)) and 0<age<200:
self.__age=age
def __count_person(self): #私有方法
return Person.COUNT ,22 #返回一个类变量
def get_count(self): #在实例方法中调用私有方法
return self.__count_person()
#私有方法:方法名前需要有两个__。只能在类的内部的其他方法中调用私有方法
#在类的外部不允许直接调用私有方法。
p1=Person("小草",3) #实例化的时候,自动调用__init__方法,将数据传入构造方法中的name
p2=Person("小花",5)
print(p1.get_age())
#p1.age=11 #实例变量的值可以在外面改变,不安全
#print(p1.__age) #会报错,因为禁止从外部访问私有变量
p1.__age=-2 #并没有改变私有变量,只是生成一个新的实例变量__age。和类里面的self.__age不是同一个变量
print(p1.get_age())
#怎么不让外面的代码随便更改,必须走实例方法?——通过私有变量:__xxxx
#私有变量:self.__xxx。在类外面禁止访问,不能通过实例名、类名等访问。例如实例名.私有变量名 是无法读到
#只能通过访问类中包含私有变量的方法调用,类中所有实例方法均可以调用私有变量
#类变量也可以私有化
print(p1.get_count()) #调用实例方法,该实例方法在类中调用了私有方法
类的内置方法
class Person: #类定义,类对象:类变量和方法
COUNT=0 #类变量
def __init__(self,name,age): #构造函数(方法)
self.name=name #name是局部变量,存到实例变量中
self.__age=age
Person.COUNT+=1 #对类变量进行累计
def __str__(self): #当你打印一个实例时候,会自动调用——>print(p1)
return "%s很可爱。" % self.name
def __repr__(self): #在交互模式下,不使用print,直接写实例变量名称则直接自动调用此方法
return "%s在努力。" % self.name
def __iter__(self): #把实例编程一个可迭代的对象
return iter("hello")
#iter("hello")和"hello"区别:
# "hello"直接存在内存中。
# iter("hello")每次只有一个值存储在内存中,当迭代时候,去取下一个值,这样就实现了节省内存的目的。
p1=Person("小花",3)
p2=Person("小草",5)
print(p1) #调用__str__方法
repr(p1) #在交互模式下可直接打印返回内容
print(repr(p1)) #加print模拟交互模式
#若没有定义__str__方法,但是定义了__repr__方法,则print(实例名)会自动调用__(repr)__方法
for i in p1: #调用__iter__方法
print(i)
#for i in p1触发了一个机制,自动调用p1实例的__iter__方法
#该代码等价于:for i in iter(["hello"])
继承
子类调用父类的构造函数有两种方法,基本语法如下: 1、super(subclassName, self).__init__( [parameter1[,parameter2....]]) 2、superclassName.__init__(self, [parameter1[,parameter2....]])
#继承:子类继承父类,自动获取父类中的实例变量和实例方法,不能继承私有变量和私有方法
#统一管理
class Person: #父类中存大家都有的信息
def __init__(self,name):
self.name = name
def get_name(self):
return self.name
def set_name(self,value):
self.name =value
class AsianPerson(Person):
#子类中存个性化信息,子类实际上是基于父类做的扩展
def __init__(self,name):
Person.__init__(self,name)
self.hair_color ="black"
a=AsianPerson("小花")
print(a.get_name())
a.set_name("小草")
print(a.name)
print(a.hair_color)
#继承:子类继承父类,自动获取父类中的实例变量和实例方法,不能继承私有变量和私有方法
#统一管理
class Person: #父类中存大家都有的信息
def __init__(self,name):
print("Person父类被实例化了!")
self.name=name
class AsianPerson(Person):
pass
a=AsianPerson()
#当子类没有实现__init__方法,就会调用父类的__init__方法,若父类中的__init__方法需要传入参数,则会报错。
#需要在实例化时候传入参数。
#继承:子类继承父类,自动获取父类中的实例变量和实例方法,不能继承私有变量和私有方法
#统一管理
class Person: #父类中存大家都有的信息
def __init__(self,name):
print("Person父类被实例化了!")
self.name=name
self.__value=100
def __print__info(self):
print("私有方法被调用")
#子类中存个性化的信息,子类实际是基于父类做的扩展
class AsianPerson(Person):
def __init__(self,color): #子类构造方法,明确调用父类的构造方法
#子类构造方法没有调用父类构造方法,那么父类的构造方法不会被自动调用
#Person.__init__(self,name)
self.color = color
#print(self.__print__info()) #会报错,父类私有方法和变量无法被子类调用
a=AsianPerson("小花","black")
#当子类没有实现__init__方法,就会调用父类的__init__方法,若父类中的__init__方法需要传入参数,则会报错。
#需要在实例化时候传入参数。
#总结:
#子类一定实现__init__方法,明确调用父类__init__方法。把所有的实例变量都初始化,那么后续使用肯定没问题。
#重写override
class Person: #父类中存大家都有的信息
def __init__(self,name):
self.name=name
def print_info(self):
print("打印父类信息")
class AsianPerson(Person):
def __init__(self,name,color):
Person.__init__(self,name)
self.color=color
#重写override:将父类方法重写
def print_info(self):
print("打印子类信息")
Person.print_info(self) # 子类方法也可以明确调用父类方法
a=AsianPerson("小花","pink")
a.print_info() #优先调用子类中的同名方法,如果没有则调用父类的同名方法
#多继承
class Person: #父类中存大家都有的信息
def __init__(self,name):
self.name=name
def print_info(self):
print("2打印父类信息")
class AsianPerson(Person):
def __init__(self,name,color):
Person.__init__(self,name)
self.color=color
#重写override:将父类方法重写
def print_info(self):
print("1打印子类信息")
Person.print_info(self) # 子类方法也可以明确调用父类方法
class Chinese_Person(AsianPerson):
def __init__(self,name,color):
AsianPerson.__init__(self,name,color)
c=Chinese_Person("小花","pink")
c.print_info()
#例子:
class Member:
def __init__(self,school,name):
self.name=name
self.school=school
def get_name(self):
return self.name
def get_school(self):
return self.school
def set_name(self,name):
self.name=name
def set_school(self,school):
self.school=school
class Teacher(Member):
def __init__(self,school,name,teacher_Id,subject,salary):
Member.__init__(self,school,name)
self.teacher_Id=teacher_Id
self.subject=[]
if isinstance(subject,str):
self.subject.append(subject)
elif isinstance(subject,(list,tuple)):
for i in subject:
self.subject.append(i)
self.salary=salary
def set_salary(self,salary):
self.salary=salary
def get_salary(self):
return self.salary
def set_subject(self,subject,opt="add"):
if opt=="add":
self.subject.append(subject)
else:
try:
self.subject.remove(subject)
except:
print("%s课程不存在,无法删除" % subject)
def get_subject(self):
return self.subject
def set_teacher_Id(self,teacher_Id):
self.teacher_Id=teacher_Id
def get_teacher_Id(self):
return self.teacher_Id
def print_info(self):
print("%s老师的ID是:%s\n所在学校是%s\n工资是%s\n教的课程是%s" %
(self.name,self.teacher_Id,self.school,self.salary,self.subject))
class Student(Member):
def __init__(self,school,name,student_id,subject,classes):
Member.__init__(self,school,name)
self.student_id=student_id
self.subject = []
if isinstance(subject, str):
self.subject.append(subject)
elif isinstance(subject, (list, tuple)):
for i in subject:
self.subject.append(i)
self.classes=classes
def set_classes(self,classes):
self.classes=classes
def get_classes(self):
return self.classes
def set_student_id(self,student_id):
self.student_id=student_id
def get_student_id(self):
return self.student_id
def set_subject(self,subject,opt="add"):
if opt=="add":
self.subject.append(subject)
else:
try:
self.subject.remove(subject)
except:
print("%s课程不存在,无法删除" % subject)
def get_subject(self):
return self.subject
def print_info(self):
print("%s学生的ID是:%s\n所在学校是%s\n班级是%s\n学的课程是%s" %
(self.name,self.student_id,self.school,self.classes,self.subject))
t=Teacher("一中","王老师","001",["数学","英语"],"3000")
s=Student("一中","王小花","002",["数学","英语"],"三年级三班")
t.print_info()
print("*"*20)
s.print_info()