这篇教程Python面向对象三大特征 封装、继承、多态写得很实用,希望能帮到您。
1、封装封装: 根据 职责 将 属性 和 方法 封装到一个 抽象的类 中将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样无需关心方法 - 内部的具体实现,从而隔离了复杂度
- 封装是面向对象编程的一大特点
- 面向对象编程的第一步。将属性和方法封装到一个抽象的类中
- 外界使用类创建对象,然后让对象调用方法
- 对象方法的细节都封装在类的内部
前言:根据需求分析,完成案例 
1 class Person: 2 def __init__(self,name,weight): 3 self.name = name 4 self.weight = weight 5 6 # 内置函数,可设置print打印输出地址时的特定显示,因此必须要有返回值 7 def __str__(self): 8 return "我是%s,体重是%.1f公斤"%(self.name,self.weight) 9 10 def run(self):11 self.weight -= 0.512 print("%s通过跑步体重减少"%self.name)13 def eat(self):14 self.weight+=115 print("%s吃太多,体重增加"%self.name)16 17 p1 = Person("小明",65)18 print(p1) #我是小明,体重是65.0公斤19 p1.eat() #小明吃太多,体重增加20 p1.run() #小明通过跑步体重减少21 print(p1) #我是小明,体重是65.5公斤22 print("*"*25)23 p2 = Person("小美",45)24 print(p2) #我是小美,体重是45.0公斤25 p2.eat() #小美吃太多,体重增加26 p2.run() #小美通过跑步体重减少27 print(p2) #我是小美,体重是45.5公斤28 print(p1) #我是小明,体重是65.5公斤 
注意:在开发时,被使用的类需要先开发 1 #创建房子类 2 class House: 3 def __init__(self,house_type,area): 4 self.house_type = house_type 5 self.area = area 6 self.free_area = area 7 self.item_list = [] 8 9 #添加家具10 def add_item(self,item):11 #判断面积是否足够添加家具12 if item.area<self.free_area:13 self.item_list.append(item.name)14 self.free_area -= item.area15 print("添加%s,占用面积%.1f"%(item.name,item.area))16 else:17 print("面积不足无法添加")18 19 #输出房子打印20 def __str__(self):21 #Python可以自动将一对括号内的代码连接到一起22 return ("该房子的户型:%s/n总面积为:%.1f平米/n剩余面积为:%.1f平米/n家具:%s"23 %(self.house_type,self.area,self.free_area,self.item_list))24 25 #创建家具对象26 jj1 = HouseItem("席梦思",4)27 jj2 = HouseItem("衣柜",2)28 jj3 = HouseItem("餐桌",1.5)29 print(jj1) #家具席梦思,占地面积为:4.0平米30 print(jj2) #家具衣柜,占地面积为:2.0平米31 print(jj3) #家具餐桌,占地面积为:1.5平米32 print("-"*30)33 #创建房子对象,并添加家具34 hs = House("大平层",6)35 hs.add_item(jj1)36 hs.add_item(jj2)37 hs.add_item(jj3)38 print("-"*30)39 print(hs)40 41 #运行结果42 家具席梦思,占地面积为:4.0平米43 家具衣柜,占地面积为:2.0平米44 家具餐桌,占地面积为:1.5平米45 ------------------------------46 添加席梦思,占用面积4.047 面积不足无法添加48 添加餐桌,占用面积1.549 ------------------------------50 该房子的户型:大平层51 总面积为:6.0平米52 剩余面积为:0.5平米53 家具:['席梦思', '餐桌']
1.1 私有属性和私有方法提高程序的安全性:
在实际开发中,对象的某些属性或方法只希望在类的内部被使用,而不希望在外部被访问到 在Python 中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前面使用两个“ _ ”(私有属性)
在Python中其实并没有真正的私有属性、私有方法:
- 给属性、方法命名时,实际是对名称做了一些特殊处理,使得类对象无法直接访问。
- 但是如果一定要从外界访问私有属性、私有方法的话,那么只需要在私有属性、私有方法前加上_类名
例:stu_1._Student__age stu_1._Student__show_1() 注意:切记在开发时,不要以这种方式去访问私有属性和私有方法 1 #私有属性、私有方法 2 class Student: 3 def __init__(self,name,age): 4 self.name = name 5 self.__age = age #使用(__属性名)的方式将age声明为私有属性 6 7 def show(self): 8 print(self.name,"的年龄为:",self.__age) #可以在类的内部使用私有属性 9 10 def __show_1(self): #使用(__方法名)的方式将show_1定义为私有方法11 print("这是{}的私有方法".format(self.name))12 13 stu_1 = Student("张三",20)14 stu_1.show() #由此可见可以在类的内部使用私用属性15 print(stu_1.name)16 #print(stu_1.__age) #代码报错,因为在类对象中并不能访问类的私有属性17 18 #stu_1.__show_1() #代码报错,因为在类对象中并不能访问类的私有属性19 20 """21 在Python中起始并没有真正的私有属性、方法:22 给属性、方法命名时,实际是对名称做了一些特殊处理,使得类对象无法直接访问。23 但是如果一定要从外界访问私有属性、方法的话,那么只需要在私有属性、方法前加上_类名24 例:stu_1._Student__age stu_1._Student__show_1()25 """26 print(stu_1._Student__age)27 stu_1._Student__show_1()28 29 运行结果:
张三 的年龄为: 20 张三 20 这是张三的私有方法
注意: 子类能继承父类的私有属性和私有方法
1 class A: 2 def __init__(self): 3 self.num1 = 100 4 self.__num2 = 200 5 6 def __fun(self): 7 print("这是一个私有方法",self.__num2) 8 9 class B(A):10 pass11 12 b = B()13 print(b._A__num2)14 # print(b._b__num2) #代码报错,因为子类不能继承父类的私有方法和私有属性15 b._A__fun()16 # b._B__fun()17 print(dir(b))18 """19 运行结果:20 20021 这是一个私有方法 20022 ['_A__fun', '_A__num2', '__class__', 23 '__delattr__', '__dict__', '__dir__', 24 '__doc__', '__eq__', '__format__', '__ge__',25 '__getattribute__', '__gt__', '__hash__', 26 '__init__', '__init_subclass__', 27 '__le__', '__lt__', '__module__', 28 '__ne__', '__new__', '__reduce__', 29 '__reduce_ex__', '__repr__', '__setattr__', 30 '__sizeof__', '__str__', '__subclasshook__', 31 '__weakref__', 'num1']32 """ 子类对象可以调用父类的公有方法,在父类的公有方法中调用父类的私有方法和私有属性,那么子类对象就可以间接的使用该共有方法访问父类的私有属性和私有方法
2、继承 - 实现代码的重用,相同的代码不需要重复编写
- 继承的语法格式
- 子类 继承 父类,可以直接 享受 父类中已经封装好的方法,不需要再次开发
- 子类 中应该根据 职责,封装 子类特有的 属性和方法
- 继承的传递性:子类拥有父类以及父类和父类中封装的所有属性和方法

1 #单继承 2 class Animal: 3 def eat(self): 4 print("吃") 5 def drink(self): 6 print("喝") 7 def run(self): 8 print("跑") 9 def sleep(self):10 print("睡")11 12 class Dog(Animal):13 def bark(self):14 print("叫")15 16 class Cat(Animal):17 def catch(self):18 print("抓老鼠")19 20 class XiaoTianQuan(Dog):21 def fly(self):22 print("飞")23 24 xtq = XiaoTianQuan()25 xtq.eat()26 xtq.bark()27 #xtq.catch() #报错,因为xiaotianquan的父类及父类的父类都没有该方法
2.1 方法的重写如果在子类中重写了父类的方法,在子类对象调用方法时,会调用子类重写的方法 
1 #方法重写 2 class Animal: 3 def eat(self): 4 print("吃") 5 def drink(self): 6 print("喝") 7 def run(self): 8 print("跑") 9 def sleep(self):10 print("睡")11 12 class Dog(Animal):13 def bark(self):14 print("叫")15 16 class Cat(Animal):17 def catch(self):18 print("抓老鼠")19 20 class XiaoTianQuan(Dog):21 def fly(self):22 print("飞")23 24 def bark(self):25 print("像神一样的叫")26 27 xtq = XiaoTianQuan()28 xtq.bark() #像神一样的叫
2.2 在子类方法中调用父类方法 - 方法一:使用
super(). 方法名 推荐使用 - 方法二:使用父类名.方法名
(self) 在python2.x 中 只能使用这个方式 1 #在子类方法中调用父类方法 2 class Animal: 3 def eat(self): 4 print("动物吃") 5 def drink(self): 6 print("动物喝") 7 def run(self): 8 print("动物跑") 9 def sleep(self):10 print("动物睡")11 12 class Dog(Animal):13 def bark(self):14 print("狗叫")15 16 class Cat(Animal):17 def catch(self):18 print("抓老鼠")19 20 class XiaoTianQuan(Dog):21 def fly(self):22 print("像神一样的飞")23 def bark(self):24 #1.针对子类特有的需求,编写的代码25 print("像神一样的叫")26 #2.方法一:使用super().调用原本封装在父类中的方法27 super().bark()28 #3.方法二:使用super().调用原本封装在父类中的方法29 Dog.bark(self)30 #4.增加子类其他的代码31 print("------------------")32 xtq = XiaoTianQuan()33 xtq.bark()34 """ 运行结果:
像神一样的叫 狗叫 狗叫 ------------------ """
2.3 多继承概念: 子类 可以拥有 多个父类,并且具有 所有父类的属性 和 方法
例如:孩子 会继承自己 父亲 和 母亲 的特性 
1 #多继承 2 class A: 3 def text(self): 4 print("这是A类的text方法") 5 class B: 6 def fun(self): 7 print("这是B类的fun方法") 8 class C(A,B): 9 pass10 c = C()11 c.text() #这是A类的text方法12 c.fun() #这是B类的fun方法 注意事项: 如果 不同的父类 拥有相同的属性名或者相同的方法名,子类对象在调用方法和属性时,会调用那个父类的呢?
提示:在开发时,应该尽量避免这种容易产生混淆的情况! Python使用pyfinance包进行证券收益分析 python编程webpy框架模板之def with学习 |