面向对象的三大特性 : 继承 多态 封装
多态:一个类表现出多种形态:通过继承来实现的
在python中:由于函数的参数不需要指定数据类型,所以也不需要通过继承的形式来统一一组类的类型
换句话说,所有的对象都有有一个共同的父类(object),即类型都可以是object类型,所以python中处处是多态。
在Java中:在一个函数中需要给参数指定数据类型,如果这个地方可以接受俩个以上的类型的参数,那么这些类型都应该定义一个共同的父类,这个父类是所以子类对象的类型。
就是运用多态来解决传参数的时候,数据类型的规范问题。
鸭子类型:指如果看起来像,叫声像鸭子,那么它就是鸭子
不是明确的通过继承实现的多态。而是通过一个模糊的概念来 判断这个函数能不能接受这个类型的参数。
例:利用标准库中定义的各种“与文件类似”的对象,尽管这些对象的工作方式像文件,但他们没有继承内置文件对象的处理方法
封装:
封装的好处:将变化隔离;便于使用;提高复用性;提高安全性
封装的原则:将不需要对外提供的内容都隐藏起来,把属性隐藏,提供公共方法对其访问
广义上的封装:就是把属性函数(打包)都放在类里,方便类的对象进行调用
就是只有这个类实例化的对象才能使用类中的方法
狭义上的封装:就是私有的
class Goods: __discout = 0 #在类中定义私有的 就是 __变量名 这样的格式 print(__discout) #直接打印 0 # print(Goods.__discount) #报错。说明在类的外部不能直接引用私有的静态变量 print(Goods.__dict__) #可以通过查看类中的所有属性和方法 找到'_Goods__discout': 0, print(Goods._Goods__discout) #打印 出 0 从编程规范的角度上来说,我们不能再类的外部使用
私有的变量
类中的静态变量和方法名在程序的加载过程中就已经执行完了,而不是在调用的时候才加载
当类中所有的属性加载完之后,才在内存中显示出这个类的名字。
私有的静态属性可以在类的内部直接使用,它的作用就是为了隐藏某个变量的值
class Student: def __init__(self,name,age): self.__name = name self.age = age def name(self): #可以通过方法来查看私有的属性 return self.__name l1 = Student("alex",18) print(l1.name()) #通过调用方法来显示私有变量的内容
class Goods: __discount = 0.7 def __init__(self,name,price): self.name = name self.__price = price @property #property 是一个装饰器函数 调用的这个方法的时候就可以不再方法后面加() 自我理解 def price(self): return self.__price * self.__discount def change_price(self,new_price): if type(new_price) is int: self.__price = new_price #私有的变量只能在内部通过方法来进行修改 else: print("本次价格修改不成功") a1 = Goods("苹果",5) print(a1.price) #3.5 #通过装饰器后,这里就可以不加括号 a1.change_price(8) #调用方法修改私有的变量 print(a1.price) #5.6
类中的私有成员:
私有的静态属性 (__name = "alex")
私有的对象属性 (self.__name = name)
私有的方法 (父类不想让子类覆盖自己的方法,可以将方法定义为私有的)
class User: __nationality = "China" #私有静态属性 def __init__(self,name,pwd): self.name = name self.__pwd = pwd #私有的对象属性 self.pwd = self.__getpwd() def __getpwd(self): #私有的方法 return hash(self.__pwd) @property def nationality(self): return User.__nationality obj = User("alex","alex123") print(obj.nationality,obj.name,obj.pwd) #China alex -1388251584925158483
我为什么要定义一个私有变量?:
我不想让你看到这个值
我不想让你修改这个值
我想让你在修改这个值的时候有一些限制
有些方法或者属性不希望被子类继承
私有变量不能再外部被定义:
例:
class A: __county = "China" #在类的内部会发生变形 变成了_A__county print(__county) A.__Language = "Chinese" #这个只是在类中增加了一个静态属性 print(A.__dict__) print(A.__Language)
私有变量不能被继承(可以使用(按照规范又不能这样做))
class A: __county = "China" def __init__(self,name): self.__name = name class B(A): # print(__county) #报错NameError: name '_B__county' is not defined print(A._A__county) #就是通过类名去调用的 def get_name(self): return self.__name b = B("alex") print(b._A__county) #China print(b.__dict__) #{'_A__name': 'alex'}