zoukankan      html  css  js  c++  java
  • 面向对象and类

    类和对象:

    1.什么叫类:类是一种数据结构,就好比一个模型,该模型用来表述一类事物(事物即数据和动作的结合体),用它来生产真实的物体(实例)。

    2.什么叫对象:睁开眼,你看到的一切的事物都是一个个的对象,你可以把对象理解为一个具体的事物(事物即数据和动作的结合体)

        (铅笔是对象,人是对象,房子是对象,狗是对象,alex是对象,配齐是对象,元昊是对象)

    3.类与对象的关系:对象都是由类产生的,上帝造人,上帝首先有一个造人的模板,这个模板即人的类,然后上帝根据类的定义来生产一个个的人

    4.什么叫实例化:由类生产对象的过程叫实例化,类实例化的结果就是一个对象,或者叫做一个实例(实例=对象)

    三大编程范式:

    编程范式即编程的方法论,标识一种编程风格

    三大编程范式:

    1.面向过程编程:捂裆派

    2.函数式编程:峨美眉妹妹派

    3.面向对象编程:少林蛋黄派

    面向对象编程与面向对象设计

    面向对象设计(Object oriented design):将一类具体事物的数据和动作整合到一起,即面向对象设计

     1 #用基于结构化的语言来实现面向对象设计
     2 def wang(name,genle,type):
     3     def jiao(dog):
     4         print("%s正在叫"%dog["name"])
     5     def chi(dog):
     6         print("%s正在吃"%dog["name"])
     7     def init(name,genle,type):
     8         dog1 ={
     9             "name":name,
    10             "genle":genle,
    11             "type":type,
    12             "jiaoa":jiao,
    13             "chi":chi
    14         }
    15         return dog1
    16     return init(name,genle,type)
    17 
    18 d1 = wang("yuanhao","gong","tianyuanquan")
    19 print(d1)
    20 d1["jiaoa"](d1)

    面向对象编程(object-oriented programming):用定义类+实例/对象的方式去实现面向对象的设计

     1 class Chinese:
     2     name = "abc"
     3     def chifan(self,x):
     4         print("姓名:%s喜欢吃%s"%(self.mingzi,x))
     5     def shuijiao(self):
     6         print("nianling:%s"%self.nianling)
     7     def __init__(self,name,age):
     8         self.mingzi = name
     9         self.nianling = age
    10 f1 = Chinese("alex",18)
    11 f1.chifan("eat")
    12 f1.shuijiao()

    类的声明

     1 大前提:
     2 1.只有在python2中才分新式类和经典类,python3中统一都是新式类
     3 2.新式类和经典类声明的最大不同在于,所有新式类必须继承至少一个父类
     4 3.所有类甭管是否显式声明父类,都有一个默认继承object父类(讲继承时会讲,先记住)
     5 在python2中的区分
     6 经典类:
     7 class 类名:
     8     pass
     9 
    10 经典类:
    11 class 类名(父类):
    12     pass
    13 
    14 在python3中,上述两种定义方式全都是新式类
    python3中声明类:
    1  1 '''
     2  2 class 类名:
     3  3     '类的文档字符串'
     4  4     类体
     5  5 '''
     6  6 
     7  7 #我们创建一个类
     8  8 class Data:
     9  9     pass
    10 10 
    11 11 #用类Data实例化出一个对象d1
    12 12 d1=Data()
    
    

    类的属性

    类有数据属性跟函数属性(又称方法属性)

     1 class Chinese:
     2     name = "abc"
     3     def chifan(self,x):
     4         print("姓名:%s喜欢吃%s"%(self.mingzi,x))
     5     def shuijiao(self):
     6         print("nianling:%s"%self.nianling)
     7     def __init__(self,name,age):#为实例定制数据属性,可以使用类的一个内置方法__init__()该方法,在类()实例化是会自动执行
     8         self.mingzi = name
     9         self.nianling = age
    10 f1 = Chinese("alex",18)   #类的实例化,相当于运行__init__函数,将参数传给__init函数体中对应的位置,生成一个字典,其中self即代表f1自身
    11 f1.chifan("eat")#通过.调用类的属性,首先会在__init__作用域内查找,若没找到会到类的属性中寻找,实例化生成的对象只具备数据属性,调用的方法为类的属性并非生成的对象所具备的属性
    12 f1.shuijiao()

    有两种方法查看类的属性

    dir(类名):查出的是一个名字列表

    类名.__dict__:查出的是一个字典,key为属性名,value为属性值

    1 class Chinese:
    2     name = "abc"
    3     def chifan(self):
    4         print(123)
    5     def shuijiao(self):
    6         print("456")
    7 print(Chinese.name)#打印的是name属性对应的内容
    8 print(Chinese.__dict__)#显示结果是一个字典,包含类的所有属性:属性值 
    9 print(dir(Chinese))#显示结果是一个列表,包含类(包含内建属性在内的)所有的属性名

     特殊的类属性

    __name__,类的名字

    __doc__,查看类的文档字符串

     __module__,类定义所在的模块__class__,实例C对应的类(仅新式类中) 

    类的方法属性增删改查:

     1 class math:
     2     country = "China"
     3     def chi(self,food):
     4         print("%s正在吃%s"%(self.mingzi,food))
     5     def __init__(self,name):
     6         self.mingzi = name
     7 f1 = math("alex")
     8 print(math.country)    #查看
     9 # print(dir(math))
    10 # print(math.__dict__)
    11 def yundong(self,hobby):#增加
    12     print("%s正在%s"%(self.mingzi,hobby))
    13 math.aihao = yundong
    14 #print(math.__dict__)
    15 f1.aihao("打篮球")
    16 #del math.chi
    17 #print(math.__dict__)
    18 def aichi(self,food):#修改
    19     print("%s很开心的吃%s"%(self.mingzi,food))
    20 math.chi =aichi
    21 f1.chi("")

    类的数据属性增删改查:

     1 class math:
     2     country = "China"
     3     def chi(self,food):
     4         print("%s正在吃%s"%(self.mingzi,food))
     5     def __init__(self,name,age):
     6         self.mingzi = name
     7         self.nianling = age
     8 
     9 f1 = math("alex",18)
    10 print(f1.__dict__)   #查看
    11 f1.mingzi = "eric" #修改
    12 print(f1.__dict__)
    13 f1.xingbie = ""  # 增加
    14 del f1.mingzi    #删除
    15 print(f1.__dict__

    类属性与对象(实例)属性

    1.实例化会自动触发init函数的运行,最后返回一个值即实例,我们要找的实例属性就存放在init函数的局部作用域里

    2.类有类的属性字典,就是类的作用域,实例有实例的属性字典,即实例的作用域

    3.综上,一个点代表一层作用域,obj.x先从自己的作用域找,自己找不到去外层的类的字典中找,都找不到,就会报错

    4.在类中没有使用点的调用,代表调用全局变量

    1 country = "China"
    2 class Chinese:
    3     country = "japan"
    4     def __init__(self,name):
    5         self.mingzi = name
    6         print(country)#打印的是普通变量country,非类结构中的变量,要调用类中的变量要用"."调用
    7 f1 = Chinese("alex")

    静态属性,类方法,静态方法

    1 class Room:
     2     arg = 123
     3     def __init__(self,name,weith,lenth,height):
     4         self.mingzi = name
     5         self.kuandu = weith
     6         self.changdu = lenth
     7         self.gaodu = height
     8     @property#静态属性,将实例化对象变成类的数据属性,将该方法封装起来,作用可隐藏逻辑代码,直接用实例+"."调用该方法
     9     def tiji(self):
    10         return self.kuandu*self.changdu*self.gaodu
    11 
    12     @classmethod#类方法,专门供类使用,与实例无关,类方法只能访问类相关的属性,不能访问实例属性,与实例无关
    13     def tell_info(cls,x):#默认参数cls不可变,为类名,后边可接参数
    14         print(cls)
    15         print("------>",Room.arg,x)
    16 
    17     @staticmethod   #静态方法 ,类的静态方法,没有默认参数,不能使用类变量和实例变量
    18     def op(x,y,z):
    19         print(x,y,z)
    20 f1 = Room("alex",10,50,20)
    21 print(f1.tiji)#由于用了property方法封装该方法(已变成数据属性),故可直接调用该数据属性
    22 Room.tell_info("abc")
    23 Room.op(1,2,3)     #类传参数可以调用
    24 f1.op(1,2,3)      #实例传参数可以调用

    组合:做关联

     1 class School:
     2     def __init__(self,name,difang):
     3         self.name = name
     4         self.difang = difang
     5 class Teacher:
     6     def __init__(self,name,sex,school):
     7         self.name = name
     8         self.sex = sex
     9         self.school = school
    10 class Lesson:
    11     def __init__(self,name,price,period,techer):
    12         self.name = name
    13         self.price = price
    14         self.period = period
    15         self.techer = techer
    16 
    17 p1 = School("old boy","北京")
    18 t1 = Teacher("alex","male",p1)#将p1对象直接添加到t1对象属性中
    19 L1 = Lesson("python班",10000,"4month",t1)
     1 class School:
     2     def __init__(self,name,difang):
     3         self.name = name
     4         self.difang = difang
     5 class Teacher:
     6     def __init__(self,name,sex,school):
     7         self.name = name
     8         self.sex = sex
     9         self.school = school
    10 class Lesson:
    11     def __init__(self,name,price,period,techer):
    12         self.name = name
    13         self.price = price
    14         self.period = period
    15         self.techer = techer
    16 
    17 p1 = School("old boy","北京")
    18 t1 = Teacher("alex","male",p1)#将p1对象直接添加到t1对象属性中
    19 L1 = Lesson("python班",10000,"4month",t1)

    面向对象编程的三大特征:

    类的继承:类的继承跟现实生活中的父、子、孙子、重孙子、继承关系一样,父类又称为基类。

      python中类的继承分为:单继承和多继承

     1 class ParentClass1:
     2     pass
     3 
     4 class ParentClass2:
     5     pass
     6 
     7 class SubClass(ParentClass1): #单继承
     8     pass
     9 
    10 class SubClass(ParentClass1,ParentClass2): #多继承
    11     pass

      子类继承了基类的所有属性

     1 class Dad:
     2     money = 10
     3     def __init__(self,name):
     4         self.name = name
     5     def hit_son(self):
     6         print("打人")
     7 class Son(Dad):#继承参数“类”的所有属性
     8     money = 5000#当子级类属性跟父级类属性重名时,调用当级类方法会先从当级寻找,找不到会去父级找
     9     pass
    10 p1 = Son("eric")
    11 print(p1.name)
    12 p1.hit_son()
    13 print(p1.money)

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

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

     

    继承同时具有两种含义:

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

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

    1 接口继承
     2 import abc   #调用接口继承模块
     3 
     4 class All_file(metaclass=abc.ABCMeta):#声明某个子类兼容于某基类,定义一个接口类,子类继承接口类,并且实现接口中定义的方法
     5     @abc.abstractclassmethod   #装饰器使方法具备接口继承特性
     6     def read(self):
     7         pass
     8     @abc.abstractclassmethod
     9     def write(self):
    10         pass
    11 
    12 class Disk(All_file):#子类继承基类时,必须对基类的方法进行派生才可实例化
    13     def read(self):
    14         print("disk-read")
    15     def write(self):
    16         print("disk-write")
    17 class Cd(All_file):
    18     def read(self):
    19         print("cd-read")
    20     def write(self):
    21         print("cd-write")
    22 class Mem(All_file):
    23     def read(self):
    24         print("mem-read")
    25     def write(self):
    26         print("mem-write")
    27 p1 = Disk()
    28 p1.read(

    继承顺序:python如果继承了多个类,遵循深度优先跟广度优先顺序

    当类时经典类时,多继承情况下,会按照深度优先方式查找

    当类是新式类时,多继承情况下,会按照广度优先方式查找

    经典类与新式类的差别:新式类在定义时便自动继承了object类,而经典类没有

    新式类继承顺序:对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表

    为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
    而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
    1.子类会先于父类被检查
    2.多个父类会根据它们在列表中的顺序被检查
    3.如果对下一个类存在两个合法的选择,选择第一个父类

     1 继承顺序
     2 
     3 
     4 class A:
     5     def test(self):
     6         print("testA")
     7 class B(A):
     8     def test(self):
     9         print("testB")
    10 class C(A):
    11     def test(self):
    12         print("testC")
    13 class D(B):
    14     def test(self):
    15         print("testD")
    16 class E(C):
    17     def test(self):
    18         print("testE")
    19 class F(D,E):
    20     def test(self):
    21         print("testF")
    22 f1 = F()
    23 print(F.__mro__)#(<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
    24 f1.test()#实例调用方法时,遵循mro顺序,会优先从子级寻找,找不到往上,先广度优先,若还找不到会找最深一级,若还没有会报错

    子类中调用父类方法

     1 class jiaotong:
     2     def __init__(self,name,speed):
     3         self.name = name
     4         self.speed = speed
     5     def run(self):
     6         print("%srunning!"%self.name)
     7 class bicycle(jiaotong):
     8     def __init__(self,name,speed,type):
     9         #jiaotong.__init__(self,name,speed)#第一种方法:类调用,子级继承父级,可以在调用父级方法的基础上进行派生,减少重复代码
    10         super().__init__(name,speed)#第二种方法:用内置super().调用父级方法
    11         self.type = type
    12     def run(self):
    13         jiaotong.run(self)
    14         print("%s开动了"%self.name)
    15 
    16 
    17 f1 = bicycle("danche",10,"meilida")
    18 print(f1.name,f1.speed,f1.type)
    19 f1.run()
    
    
  • 相关阅读:
    数据挖掘、数据分析的书籍推荐
    跳槽时间如何选择
    求职网站总结
    Eclipse中Applet程序运行时Applet小程序大小的设置
    统计学习导论:基于R应用——第五章习题
    统计学习导论:基于R应用——第四章习题
    统计学习导论:基于R应用——第三章习题
    Windows环境下安装IPython NoteBook
    centos7上mysql无法启动也没有日志
    CentOS 6.4下Squid代理服务器的安装与配置
  • 原文地址:https://www.cnblogs.com/jasonenbo/p/6211674.html
Copyright © 2011-2022 走看看