python开发学习 day25 面向对象(静态属性,静态方法,继承,多态,封装。。。)

一、静态属性

@property

class Room:
    tag=1
    def __init__(self,name,owner,width,length,heigh):
        self.name=name
        self.owner=owner
        self.width=width
        self.length=length
        self.heigh=heigh

    @property
    def cal_area(self):
        # print('%s 住的 %s 总面积是%s' % (self.owner,self.name, self.width * self.length))
        return  self.width * self.length

    def test(self):
        print('from test',self.name)

    @classmethod
    def tell_info(cls,x):
        print(cls)
        print('--》',cls.tag,x)#print('--》',Room.tag)
    # def tell_info(self):
    #     print('---->',self.tag)


# print(Room.tag)

# Room.test(1) #1.name
# r1=Room('厕所','alex',100,100,100000)
Room.tell_info(10)



# r1=Room('厕所','alex',100,100,100000)
# r2=Room('公共厕所','yuanhao',1,1,1)
# # print('%s 住的 %s 总面积是%s' %(r1.owner,r1.name,r1.width*r1.length))
# # print('%s 住的 %s 总面积是%s' %(r2.owner,r2.name,r2.width*r2.length))
# # r1.cal_area()
# # r2.cal_area()
# print(r1.cal_area)
# print(r2.cal_area)
# print(r1.name)
# print(r2.name)
View Code

 

二、类方法

@classmethod      只是给类使用的 ,没有绑定到实例上  ,打印类的一些信息

class Room:
    tag=1
    def __init__(self,name,owner,width,length,heigh):
        self.name=name
        self.owner=owner
        self.width=width
        self.length=length
        self.heigh=heigh

    @property
    def cal_area(self):
        # print('%s 住的 %s 总面积是%s' % (self.owner,self.name, self.width * self.length))
        return  self.width * self.length

    def test(self):
        print('from test',self.name)

    @classmethod
    def tell_info(cls,x):
        print(cls)
        print('--》',cls.tag,x)#print('--》',Room.tag)
    # def tell_info(self):
    #     print('---->',self.tag)


# print(Room.tag)

# Room.test(1) #1.name
# r1=Room('厕所','alex',100,100,100000)
Room.tell_info(10)
View Code

 

三、静态方法

@staticmethod    类的工具包,不跟类绑定,也不跟实例绑定=======》  只是名义上归属类管理,不能使用类变量和实例变量,是类的工具包

class Room:
    tag=1
    def __init__(self,name,owner,width,length,heigh):
        self.name=name
        self.owner=owner
        self.width=width
        self.length=length
        self.heigh=heigh

    @property
    def cal_area(self):
        # print('%s 住的 %s 总面积是%s' % (self.owner,self.name, self.width * self.length))
        return  self.width * self.length

    @classmethod
    def tell_info(cls,x):
        print(cls)
        print('--》',cls.tag,x)#print('--》',Room.tag)
    # def tell_info(self):
    #     print('---->',self.tag)

    @staticmethod
    def wash_body(a,b,c):
        print('%s %s %s正在洗澡' %(a,b,c))

    def test(x,y):
        print(x,y)

# Room.wash_body('alex','yuanhao','wupeiqi')

print(Room.__dict__)


r1=Room('厕所','alex',100,100,100000)

print(r1.__dict__)
# r1.wash_body('alex','yuanhao','wupeiqi')

# Room.test(1,2)
# r1.test(1,2)
View Code

 

四、组合

# class Hand:
#     pass
#
# class Foot:
#     pass
#
# class Trunk:
#     pass
#
# class Head:
#     pass
#
#
# class Person:
#     def __init__(self,id_num,name):
#         self.id_num=id_num
#         self.name=name
#         self.hand=Hand()
#         self.foot=Foot()
#         self.trunk=Trunk()
#         self.head=Head()
# p1=Person('111111','alex')


# print(p1.__dict__)

# class School:
#     def __init__(self,name,addr):
#         self.name=name
#         self.addr=addr
#
#     def zhao_sheng(self):
#         print('%s 正在招生' %self.name)
#
# class Course:
#     def __init__(self,name,price,period,school):
#         self.name=name
#         self.price=price
#         self.period=period
#         self.school=school
#
#
#
# s1=School('oldboy','北京')
# s2=School('oldboy','南京')
# s3=School('oldboy','东京')
#
# # c1=Course('linux',10,'1h','oldboy 北京')
# c1=Course('linux',10,'1h',s1)
#
# print(c1.__dict__)
# print(c1.school.name)
# print(s1)













class School:
    def __init__(self,name,addr):
        self.name=name
        self.addr=addr


    def zhao_sheng(self):
        print('%s 正在招生' %self.name)

class Course:
    def __init__(self,name,price,period,school):
        self.name=name
        self.price=price
        self.period=period
        self.school=school



s1=School('oldboy','北京')
s2=School('oldboy','南京')
s3=School('oldboy','东京')

# c1=Course('linux',10,'1h','oldboy 北京')
# c1=Course('linux',10,'1h',s1)

msg='''
1 老男孩 北京校区
2 老男孩 南京校区
3 老男孩 东京校区
'''
while True:
    print(msg)
    menu={
        '1':s1,
        '2':s2,
        '3':s3
    }
    choice=input('选择学校>>: ')
    school_obj=menu[choice]
    name=input('课程名>>: ')
    price=input('课程费用>>: ')
    period=input('课程周期>>: ')
    new_course=Course(name,price,period,school_obj)
    print('课程【%s】属于【%s】学校' %(new_course.name,new_course.school.name))
组合

 

 

五、继承

1.什么是继承

class Dad:
    '这个是爸爸类'
    money=10
    def __init__(self,name):
        print('爸爸')
        self.name=name
    def hit_son(self):
        print('%s 正在打儿子' %self.name)

class Son(Dad):
    money = 1000000000009
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def hit_son(self):
        print('来自儿子类')
# print(Son.money)
# Son.hit_son()
# print(Dad.__dict__)
# print(Son.__dict__)
s1=Son('alex',18)
s1.hit_son()
# print(s1.money)
# print(Dad.money)
# print(s1.name)
# print(s1.money)
# print(s1.__dict__)
# s1.hit_son()
继承

 

2.什么时候用继承

2.1 

当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好

2.2

当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好

 

猫:喵喵叫,吃喝拉撒

狗:汪汪叫,吃喝拉撒

 

3.继承同时具有两种含义

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

含义二,声明某个子类兼容于某基类,定义一个接口类,子类继承接口类,并且实现接口中定义的方法

 

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

继承的第二种含义非常重要,它又叫接口继承

接口继承实质上是,要求“做出一个良好的抽象,这个抽象规定类一个兼容接口,它使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”

----这在程序上叫做归一化

 

import abc
class All_file(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def read(self):
        pass

    @abc.abstractmethod
    def write(self):
        pass

class Disk(All_file):
    def read(self):
        print('disk read')

    def write(self):
        print('disk write')

class Cdrom(All_file):
    def read(self):
        print('cdrom read')

    def write(self):
        print('cdrom write')


class Mem(All_file):
    def read(self):
        print('mem read')

    def write(self):
        print('mem write')
#
m1=Mem()
m1.read()
m1.write()
View Code

 

归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合---就好像Linux的泛文件概念一样,所有的东西都可以当文件处理,不必关心他是内存,磁盘,网络还是屏幕(当然,对于底层设计者,当然也可以区分出“字符设备”和“块设备”,然后做出针对性的设计:细致到什么程度,视需求而定)

 

4. 继承顺序

import abc
class All_file(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def read(self):
        pass

    @abc.abstractmethod
    def write(self):
        pass

class Disk(All_file):
    def read(self):
        print('disk read')

    def write(self):
        print('disk write')

class Cdrom(All_file):
    def read(self):
        print('cdrom read')

    def write(self):
        print('cdrom write')


class Mem(All_file):
    def read(self):
        print('mem read')

    def write(self):
        print('mem write')
#
m1=Mem()
m1.read()
m1.write()
View Code

 

python3中全部是新式类

 

终极解密:python到底如何实现继承的,对于你定义的每一个类,,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表

为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止

而这个MRO列表的构造是通过c3线性化算法来实现的,我们不去深究这个算法的数学原理,他实际上就是合并所有父类的MRO列表并遵循如下三条准则:

1.子类会先于父类被检查

2.多个父类会根据他们在列表中的顺序被检查

3.如果对下一个类存在两个合法的选择,选择第一个父类

 

5. python2中是如何继承的

#经典类:F->D->B->A-->E-->

#F-->D->B-->E--->C--->A新式类

 

 

六.子类中调用父类的方法

class Vehicle:
    Country='China'
    def __init__(self,name,speed,load,power):
        self.name=name
        self.speed=speed
        self.load=load
        self.power=power
    def run(self):
        print('开动啦')
        print('开动啦')
class Subway(Vehicle):
        def __init__(self,name,speed,load,power,line):
           Vehicle.__init__(self,name,speed,load,power)
           self.line=line

        def show_info(self):
            print(self.name,self.speed,self.load,self.power,self.line)

        def run(self):
            Vehicle.run(self)
            print('%s %s 线,开动啦' %(self.name,self.line))
line13=Subway('北京地铁','10km/s',1000000000,'',13)

line13.show_info()

line13.run()
View Code

 

super方法的使用

class Vehicle1:
    Country='China'
    def __init__(self,name,speed,load,power):
        self.name=name
        self.speed=speed
        self.load=load
        self.power=power
    def run(self):
        print('开动啦')
        print('开动啦')
class Subway(Vehicle1):
        def __init__(self,name,speed,load,power,line):
           # Vehicle.__init__(self,name,speed,load,power)
           # super().__init__(name,speed,load,power)  #super(__class__,self).__init__(name,speed,load,power)
           super(Subway,self).__init__(name,speed,load,power)
           self.line=line
        def show_info(self):
            print(self.name,self.speed,self.load,self.power,self.line)
        def run(self):
            # Vehicle.run(self)
            super().run()
            print('%s %s 线,开动啦' %(self.name,self.line))
line13=Subway('北京地铁','10km/s',1000000000,'',13)
line13.show_info()
line13.run()

print(line13.__class__)
View Code

 

posted @ 2018-12-11 21:48  apoorgod  阅读(92)  评论(0)    收藏  举报