我们都知道,所谓的面向对象是一种程序设计思想 ,把对象作为程序为最基本单元 ,一个对象是由属性和方法构成的 :
对象 = 属性 + 方法
1.特性介绍
同时 ,在面向对象中,包含三大特性 ,分别是 : 封装,继承和多态。
2.图解说明
如果将上面的内容通过图形来进行说明的话,可以是如下图所示 :
封装
继承
多态
3.代码实践
继承代码:
# 面向对象-继承
class Student(object):
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
def show_info(self):
return "{},{},今年{}岁".format(self.name,self.sex,self.age)
# 继承Student类
class MiddleStudent(Student):
pass
# 初始化的对象是中学生
s1 = MiddleStudent('李四','男',14)
print(s1.show_info()) # 好处 :子类可以直接访问父类的方法,即拿来即用,减少功能重复实现。
print(s1.name) # 好处 :子类可以直接访问父类的属性
封装代码:
# 面向对象分装
class Student(object):
def __init__(self, name, sex, age, mobile):
self.name = name # 默认的为公共属性
self.sex = sex
self.__age = age # 私有属性 ,在前面两个__,就变为了私有属性了 。
self.__mobile = mobile
def get_age(self):
return "{}的年龄{}岁".format(self.name,self.__age) # 内部可以访问私有属性。
def __set_card(self,card): # 只有本类可以访问,包括子类也无法访问
self.card = card
def _set_city(self,city): # 只有本类和子类的可访问,外部已经无法访问,也无法导入
self.city = city
def get_city(self):
return self.city
class MiddleStudent(Student):
pass
# 初始化对象
s1 = Student('张三','男',24,'13210001000')
# print(s1.__age) # 外部已经无法访问了,运行后报错:AttributeError: 'Student' object has no attribute '__age'
# print(s1.__set_card('102010199812011210')) # 运行后报错 :AttributeError: 'Student' object has no attribute '__set_card'
s2 = MiddleStudent('李四','男',14,'13210001001')
s2._set_city('北京') # 子类仍然可以访问
print(s2.get_city())
多态代码
# 面向对象-多态
class Student(object):
def __init__(self, name):
self.name = name
def set_score(self, score):
if 0 <= score <= 100:
self.score = score
else:
raise "分数不能大于100分"
def get_score(self):
return "{}的分数为:{}".format(self.name,self.score)
# 继承Student类
class MiddleStudent(Student):
# 复写父类方法
def set_score(self, score):
if 0 <= score <= 120:
self.score = score
else:
raise "分数不能大于120分"
# 继承Student
class HighStudent(Student):
# 复写父类方法
def set_score(self, score):
if 0 <= score <= 150:
self.score = score
else:
raise "分数不能大于150分"
# 继承Student类
class SmallStudent(Student):
pass
# 定义一个接口函数,显示不同学生的分数
def score_result(student,score):
student.set_score(score)
return student.get_score()
if __name__ == '__main__':
print(score_result(SmallStudent('王二'),90)) # SmallStudent中没有run方法,故调用父类的方法
print(score_result(HighStudent('张三'),110)) # 直接调用HighStudent中的run方法
print(score_result(MiddleStudent('李四'),110)) # 直接调用MiddleStudent中的run方法
为了说明多态 ,我们单独定义了一个score_result的接口函数 ,在此函数中,我们定义了一个student参数,用于接受Student对象 ,通过Student对象调用set_score方法。这时我们就可以传入各种对象,比如Student对象 ,SmallStudent对象 ,MiddleStuent对象 ,HighStudent . 但不论什么对象 ,只要它内部有score_result方法,就会调用此对象的方法,否则调用父类的方法 ,从而实现了多态 。
那么,使用多态有什么好处呢 ? 我们可以想想 ,对于调用处来说 ,我们不希望调用的功能修改或者说尽量的少修改,这样对于调用者来说改动的就会减少 。而同时也要保留原功能具有扩展性 。那么在我们这里,你可以继续扩展出新的Student子类(新的功能) ,但是对于score_result来说,不需要做任何修改 。
4.总结
那么,对于以上的特性进行总结的话 ,可以是如下:
- 封装 :定义的类,有的属性或方法不希望被外界访问而只被内部使用,就需要用到封装 。
- 继承 : 若要使用某个类的功能 ,同时和这个类的类型相同 ,可以继承这个类 ,就可以直接使用此类的所有功能 。
- 多态 :在继承的基础上,若要想实现功能可扩展的基础上同时在调用处不做修改的话,就可以使用多态 。