面向对象(抽象类,接口类,多态,封装)

抽象类与接口类

接口类

继承有两种用途:

一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)  

二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能

示例:

class Alipay:
    def __init__(self,money):
        self.money=money
    def pay(self):
        print("用支付宝支付了%s元" % self.money)

class Taobaopay:
    def __init__(self,money):
        self.money=money
    def pay(self):
        print("用淘宝支付了%s" % self.money)
a1=Alipay(250)
a1.pay()

t1=Taobaopay(500)
t1.pay()

用支付宝支付了250元
用淘宝支付了500

实践中,继承的第一种含义意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。

继承的第二种含义非常重要。它又叫“接口继承”。
接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。

归一化设计示例:

class Alipay:
    def __init__(self,money):
        self.money=money
    def pay(self):
        print("用支付宝支付了%s元" % self.money)

class Taobaopay:
    def __init__(self,money):
        self.money=money
    def pay(self):
        print("用淘宝支付了%s" % self.money)

def pay(obj):
    obj.pay()
a1=Alipay(250)
t1=Taobaopay(500)
pay(a1)
pay(t1)
用支付宝支付了250元
用淘宝支付了500
制定规则,抽象类,接口类
from abc import ABCMeta,abstractclassmethod
class Payment(metaclass=ABCMeta):           # 抽象类(接口类):
    @abstractclassmethod
    def pay(self):pass                      # 制定了一个规范
class Alipay(Payment):
    def __init__(self,money):
        self.money=money
    def pay(self):
        print("用支付宝支付了%s元" % self.money)
class Taobaopay(Payment):
    def __init__(self,money):
        self.money=money
    def pay(self):
        print("用淘宝支付了%s" % self.money)
class Wechatpay(Payment):
    def __init__(self,money):
        self.money = money
    def pay(self):
        print('使用微信支付了%s' % self.money)
def pay(obj):
    obj.pay()
a1=Alipay(100)
a1.pay()
t1=Taobaopay(500)
pay(t1)   # 归一化设计
w1 = Wechatpay(300)
w1.weixinpay()    # 用的时候才会报错
python面向对象的三大特征之一:多态
多态: python处处是多态.
python 不管什么类型,传入函数,封装到对象中都可以.

python没有多态?他有什么? 他有鸭子类型.
鸭子类型 : 看着像鸭子,他就是鸭子.
这些类 都互称为鸭子.
class Str:
    def index(self):
        pass

class List:
    def index(self):
        pass

class Tuple:
    def index(self):
        pass

几个类中都有index方法

类的划分:

class A:

    company_name = '老男孩教育'  # 静态变量(静态字段)
    __iphone = '1353333xxxx'  # 私有静态变量(私有静态字段)


    def __init__(self,name,age): #普通方法(构造方法)

        self.name = name  #对象属性(普通字段)
        self.__age = age  # 私有对象属性(私有普通字段)

    def func1(self):  # 普通方法
        pass

    def __func(self): #私有方法
        print(666)


    @classmethod  # 类方法
    def class_func(cls):
        """ 定义类方法,至少有一个cls参数 """
        print('类方法')

    @staticmethod  #静态方法
    def static_func():
        """ 定义静态方法 ,无默认参数"""
        print('静态方法')

    @property  # 属性
    def prop(self):
        pass
View Code

广义的封装: 实例化一个对象,给对象空间封装一些属性

狭义的封装: 私有制.

私有成员:私有静态字段,私有方法,私有对象属性

 

私有静态字段

 


class A:
    name = 'alex'
    def func(self):
        print('func....')
a1 = A()
print(a1.name)
print(A.name)
alex
alex
func....

实例化对象不能访问私有静态字段
class A:
    name = 'alex'
    __age=10
    def func(self):
        print('func....')
a1 = A()
print(a1.__age)
结果:报错

类名不能访问私有静态字段
class A:
    name = 'alex'
    __age=10
    def func(self):
        print('func....')
a1 = A()
print(A.__age)
结果:报错

所以:对于私有静态字段,类的外部不能访问.
class A:
    name = 'alex'
    __age=10
    def func(self):
        print(self.__age)
        print('func....')
a1 = A()
a1.func()
10
func....

class A:
    name = 'alex'
    __age=10
    def func(self):
        print(A.__age)
        print('func....')
a1 = A()
a1.func()
10
func....
由上可知:对于私有静态字段,类的内部可以访问.
对于私有静态字段来说,只能在本类中内部访问,类的外部,派生类均不可访问.

class B:
    __money=1000000
class A(B):
    name = 'alex'
    __age=10
    def func(self):
        print(self.__age)
        print(A.__age)
        print('func....')
    def func1(self):
        print(self.__money)
        print(A.__age)
a1 = A()
a1.func1()
结果:报错

可以访问,但是工作中千万不要用.
class B:
    __money=1000000
class A(B):
    name = 'alex'
    __age=10
    def func(self):
        print(self.__age)
        print(A.__age)
        print('func....')
    def func1(self):
        print(self.__money)
        print(A.__age)
a1 = A()
print(A._A__age)
print(A.__dict__)

10
{'__module__': '__main__', 'name': 'alex', '_A__age': 10, 'func': <function A.func at 0x000001C50A5D8D90>, 'func1': <function A.func1 at 0x000001C50A5D8E18>, '__doc__': None}
View Code
私有方法
类外部不能访问
class B:
    __money = 100000
    def __f1(self):
        print('B')
class A(B):
    name = 'alex'
    def __func(self):
        print('func....')
a1 = A()
a1.__func() 
结果:报错
类的内部可以访问
class B:
    __money = 100000
    def __f1(self):
        print('B')
class A(B):
    name = 'alex'
    def __func(self):
        print('func....')
    def func1(self):
        self.__func()
a1 = A()
a1.func1()

func....

类的派生类也不能访问.
class B:
    __money = 100000
    def __f1(self):
        print('B')
class A(B):
    name = 'alex'
    def __func(self):
        print('func....')
    def func1(self):
        self.__f1()
a1 = A()
a1.func1()
结果:报错

练习题:

class Parent:
    def __func(self):
        print('in Parent func')
    def __init__(self):
        self.__func()
class Son(Parent):
    def __func(self):
        print('in Son func')
son1 = Son()
View Code

私有对象属性

 

通过对象不可以访问
class A:
    def __init__(self):
        self.__name="name"

a1 = A()
a1.__name

结果:报错

通过类内部可以访问
class A:
    def __init__(self):
        self.__name="name"
    def func(self):
        print(self.__name)
a1 = A()
a1.func()
结果:name

通过派生类不可以访问
class A:
    def __init__(self):
        self.__name="name"
    def func(self):
        print(self.__name)
class B(A):
    def func1(self):
       print(self.__name)
a1 = B()
a1.func1()
结果:报错

 

 
 
 

 

 

 
 



 
 
 
 
 
 
 
 
 


 

posted @ 2018-07-26 16:19  chenyibai  阅读(292)  评论(0编辑  收藏  举报