面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如 Student 类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
面向对象的思想是从自然界中来的,因为在自然界中,类和实例的概念是很自然的。面向对象的抽象程度比函数要高,因为一个Class既包含数据,又包含操作数据的方法。
数据封装、继承和多态是面向对象的三大特点。
class Student(object):
def __init__(self,name,score):
self.name=name
self.score=score
init方法的第一个参数永远是self,表示穿件的实例本身,在它的方法内部,可以把各种属性绑定到self,self是指创建实例的本身。
有了init方法,在创建实例的时候,就不能传入空的参数,必须传入与其方法匹配的阐述,而self本身不需要传,python解释器本身自己会把实例变量传进去。
class Student(object):
def __init__(self,name,score):
self.name=name
self.score=score
#调用
bart=Student("李四",59)
print(bart.name)
结果:
李四
数据封装
- 面向对象编程的一个重要特点就是数据封装。在上面的类中,每个实例就拥有各自的name和score这些数据,我们可以通过函数来访问。
class Student(object):
def __init__(self,name,score):
self.name=name
self.score=score
def print_score(self):
print("%s:%s" %(self.name,self.score))
#调用
bart=Student("李四",59)
# print(bart.name)
bart.print_score()
结果:
李四:59
方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据。
当我们调用方法时,我们就直接操作了对象内部的数据,不需要知道方法内部的实现细节。
访问限制
如果要让内部属性不被外部访问,可以把属性的名称加上两个下划线,变量名如果以__开头,就变成私有变量,外部不能访问。
class Student(object):
def __init__(self,name,score):
self.__name=name
self.__score=score
def print_score(self):
print("%s:%s" %(self.__name,self.__score))
#调用
bart=Student("李四",59)
# print(bart.name)
print(bart.__score)
返回结果:
print(bart.__score)
AttributeError: 'Student' object has no attribute '__score'
通过访问限制,代码更加健壮。
想要从外部获取name和score,可以给类增加get_name和get_score方法。
class Student(object):
def __init__(self,name,score):
self.__name=name
self.__score=score
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def print_score(self):
print("%s:%s" %(self.__name,self.__score))
#调用
bart=Student("李四",59)
# print(bart.name)
print(bart.get_score())
结果:
59
- “虽然我可以被访问,但是请把我视为私有变量,不要随意访问。”
python解释器对外把__name变量改成了_Student__name,所以仍然可以访问__name变量。
class Student(object):
def __init__(self,name,score):
self.__name=name
self.__score=score
# def get_name(self):
# return self.__name
#
# def get_score(self):
# return self.__score
def print_score(self):
print("%s:%s" %(self.__name,self.__score))
#调用
bart=Student("李四",59)
# print(bart.name)
print(bart._Student__name)
结果:
李四
继承和多态
- 继承的第一个好处:子类可以获取父类的全部功能。
class Animal(object):
def run(self):
print('animal is running...')
class Dog(Animal):
pass
class Cat(Animal):
pass
dog=Dog()
dog.run()
cat=Cat()
cat.run()
animal is running...
animal is running...
- 第二个好处:可以对代码做出改进。
class Animal(object):
def run(self):
print('animal is running...')
class Dog(Animal):
def run(self):
print("Dog is running")
class Cat(Animal):
def run(self):
print("cat is running")
dog=Dog()
dog.run()
cat=Cat()
cat.run()
结果:
Dog is running
cat is running
当子类和父类都存在相同的方法时,子类的方法覆盖了父类的方法,代码运行时总会调用子类的方法,这种继承的好处是多态。
- 鸭子类型:不要求严格的继承体系,一个对象只要看起来像鸭子,走起来像鸭子,那么它就可以被看做鸭子。
网友评论