面对对象--多态封装
一:多态
1:多态 ,父类被多个类单继承
不同的子类对象,调用相同的父类方法, 产生不同的执行结果,多态可以增加代码的灵活度,以继承和重写父类方法为前提,是调用方法的技巧, 不会影响到类内部设计。
1 class Game: #game类表现了Dog Sheep两种形态
2 def __init__(self,name):
3 self.name = name
4 def walk(self):
5 self.name = name
6 print('%s动作'%self.name)
7 def eat(self):
8 print('%s吃饭'%self.name)
9 class Dog(Game):
10
11 def walk(self):
12 print('%s看门!'%self.name)
13 class Sheep(Game):
14 def walk(self):
15 print('%s睡觉!'%self.name)
16 def walk(obj, work):
17 obj.walk()
d = Dog('Dog') #Dog看门!
s = Sheep('sheep')
walk(d)
walk(s) #在调用类实例方法的时候,尽量把变量视作父类类型,这样,所有子类类型都可以正常被接收
2:java 与python区别
在java中的表现:在一个函数需要给参数指定数据类型, 如果这个地方可以接受两个以上的参数, 那么这些类型应该有一个父类, 这个父类就是所有子类的对象的类型。
在python中:函数的参数不需要指定数据类型, 所以我们也不需要通过继承的形式来统一的类型, 换句话说所有的对象都是object类型, 所以python其实处处多态。
3:鸭子类型
len()#str list tuple dict set range() 可迭代对象
不是通过明确的继承实现的多态
而是通过一个模糊的概念来判断这个函数能不能接受这个类型的参数
二 :封装
1:广义的封装
建立一个类把相关的动作放到类,只有这个类的对象才能使用定义类中的方法
2:狭义的封装
1 class P: 2 __name = 'leiwenxuan' 3 def fun(self): 4 print('I am %s'%self.__name) #在类里面可以调用
print(self.__name) #这里会报错, 在这个类加载之前, __name 还没出现在内存空间中
5 p1 = P() 6 # print(p1.__name) #报错P里面没有那么熟悉 7 print(dir(p1)) #查看p1里面的属性和方法 发现_P__name 存在 8 '''['_P__name', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__init_subclass__', '__le__',
'__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__']''' 9 print(p1._P__name) 10 p1.fun() #I am leiwenxuan
在类的外部不能引用私有的静态变量, 类中的静态变量和方法名在程序加载过程中就已执行完了, 不需要等待调用,私有的静态属性可以在类的内部使用, 用了隐藏某个变量的值。
3:私有类的格式:
1 class P: 2 __name = 'wen' #私有的静态变量 3 #在类空间存储的变量名字:_P__name 可以通过__dict__ dir() 4 print(P.__dict__) 5 print(dir(P))
虽然我们可以通过_p__name 调用变量,但是在编程规范的角度出发, 我们不能再类的外部使用私有的变量,否则破坏了封装性,对后期项目的维护造成极大的困难
1 class Shopping:
2 __discount = 1
3 def __init__(self, name, price):
4 self.name = name
5 self.__price = price
6 def price(self):
7 print('9999999999')
8 return self.__price* Shopping.__discount
9
10 def Change_price(self, new_price):
11 print(type(new_price) is int)
12 if type(new_price) is int:
13 self.__price = new_price
14 s = Shopping('banan', 10)
15 print(s.price()) #10
16 s.Change_price(7)
17 #修改成功 私有的对象属性可以在类里面修改
18 print(s.price()) # 7
19 print(dir(Shopping))
20 print(s.__dict__)
4:私有的方法:
1 class User:
2 def __init__(self, name, password):
3 self.name = name
4 self.__pwd = password
5 self.pwd = self.__getpwd()
6
7 def __getpwd(self):#私有方法 '_User__getpwd' 外部不可以调用
8 return hash(self.__pwd)
9 p = User('lws','12345')
10 print(p.pwd)
11 print(dir(p))
5:为什么要定义一个私有变量
1:不想让你看到这个值
2:不想让你修改这个值
3:让你修改这个值的时候有一些限制
4:有些方法和属性不希望被子类继承
6:私有变量能不能再外部被定义
不可以, 在外部定义只是添加了一个__name 一个属性
7:私有变量可以被继承?
1 class A: 2 __name = 'wxn' 3 class B(A): 4 # print(_B__name) 5 #name '_B__name' is not defined 6 def fun(self): 7 print(self.__name) #name 存在形式_A__name 8 9 b = B() 10 print(dir(b))