zoukankan      html  css  js  c++  java
  • 面向对象——类与对象篇(第一章)

    一、什么是面向对象?

      想要学习面向对象,就要先知道面向过程。

    面向过程
    面向过程:面向过程的程序的核心是过程(流水线思维),就是关心解决问题的步骤。
    
        面向过程
      优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源,比如单片机、嵌入式开发、Linux/Unix等一般采用面向过
    
         程开发,性能是最重要的因素。 
      缺点:没有面向对象易维护、易复用、易扩展
        适用场景: 一旦完成很少改变的场景(著名的Linux内核、git、以及Apache HTTP Server等)
    
    

     面向对象

    面向对象:面型对象的程序设计的核心是对象。
    
        (万物皆对象,需要关心程序中各元素(对象)的属性,及其方法) 
    
          比如说:
    
              人的属性:姓名,年龄,身高,体重
    
              人的技能:思考,玩耍,学习 。。。
    
      优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护 
      缺点:性能比面向过程低
    认识类和对象:
    简单点:
    
        类:具有相同特征的一类事物(人、狗、老虎)    # 都是动物类别,还可以细分位人类,狗类,虎类
    
        对象/实例:具体的某一个事物(对于人类来说,具体到某一个人:爱因斯坦、牛顿、等等)

     

    类的创建: 

    class Person:   #定义一个人类
        role = 'person'  #人的角色属性都是人(类的静态属性)
        def walk(self):  #人都可以走路,也就是有一个走路方法,也叫动态属性(类的方法,如果有实例化对象,该对象也具有该方法)
            print("person is walking...")

     

    类的属性引用与实例化  

       属性引用(类名.属性)

    复制代码
    class Person:   #定义一个人类
        role = 'person'  #静态属性
        def walk(self):  #动态属性 方法(函数) 默认带一个self参数
            print("person is walking...")

      查看与修改静态变量

    查看静态变量的第一种方式
      print
    (Person.__dict__) # 内置的双下方法   print(Person.__dict__['静态变量'])
    修改:   Person.
    __dict__['静态变量'] = 456 # 报错   print(Person.__dict__['静态变量']) 查看静态变量的第二种方式   print(Person.静态变量) # 123 值   print(Person.role)
    修改:   Person.静态变量
    = 456 # 正确操作   print(Person.静态变量)
    删除:   
    del Person.静态变量   print(Person.__dict__)

    总结:
    
     引用静态变量
       1.类名.__dict__['静态变量名'] 可以查看,但是不能删改
       2.类名.静态变量名 直接就可以访问,可以删改
       删除一个静态变量 del 类名.静态变量名
      引用动态变量
       1.类名.方法名 查看这个方法的内存地址
       1.类名.方法名(实参) 调用了这个方法,必须传一个实参,这个实参传给了self

      类的基本参数(补充)

    一:我们定义的类的属性到底存到哪里了?有两种方式查看
    dir(类名):查出的是一个名字列表
    类名.__dict__:查出的是一个字典,key为属性名,value为属性值
    
    二:特殊的类属性
    类名.__name__# 类的名字(字符串)
    类名.__doc__# 类的文档字符串
    类名.__base__# 类的第一个父类(在讲继承时会讲)
    类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
    类名.__dict__# 类的字典属性
    类名.__module__# 类定义所在的模块
    类名.__class__# 实例对应的类(仅新式类中)
    复制代码

    对象

      实例化:类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征

    class Person:
      role = 'person' # 静态属性
      def __init__(self,name,sex,hp,ad):
        self.name = name # 对象属性 属性
        self.sex = sex
        self.hp = hp
        self.ad = ad
      def attack(self):
        print('%s发起了一次攻击'%self.name)

    alex = Person('a_sb','不详',1,5)
    boss_jin = Person('金老板','女',20,50)

    alex.attack() # Person.attack(alex)
    boss_jin.attack() # Person.attack(boss_jin)

    
    

    实例化的过程:
       1.创造一个实例,将会作为一个实际参数 # python
       2.自动触发一个__init__的方法,并且把实例以参数的形式传递给__init__方法中的self形参
       3.执行完__init__方法之后,会将self自动返回给alex
       __init__方法 :初始化方法,给一个对象添加一些基础属性的方法,一般情况下是针对self的赋值

    语法:对象名 = 类名(参数)

      查看对象的属性与调用方法

    print(alex.name)     #查看属性直接 对象名.属性名
    print(alex.walk())   #调用方法,对象名.方法名()


    对象
       在类的内部 self是本类的一个对象
       在类的外部,每一个对象都对应着一个名字,这个对象指向一个对象的内存空间
    属性的调用:
       对象名.属性名 第一种调用方法
       对象名.__dict__['属性名'] 第二种调用方法
    方法的调用 :
       类名.方法名(对象名) # 那么方法中的self参数就指向这个对象
       对象名.方法名() # 这样写 相当于 方法中的self参数直接指向这个对象

     

    面向对象的交互

    对象可以作为参数传递给类中的方法

    示例一:
    class
    Person: role = 'person' # 静态属性 def __init__(self,name,sex,hp,ad): self.name = name # 对象属性 属性 self.sex = sex self.hp = hp #血量 self.ad = ad #攻击力 def attack(self,d): d.hp -= self.ad print('%s攻击了%s,%s掉了%s点血'%(self.name,d.name,d.name,self.ad)) class Dog: def __init__(self,name,kind,hp,ad): self.name = name self.kind = kind self.hp = hp self.ad = ad def bite(self,p): p.hp -= self.ad print('%s咬了%s一口,%s掉了%s点血' % (self.name, p.name, p.name, self.ad))



    alex = Person('a_sb','不详',1,5)     # 实例化一个人对象alex
    boss_jin = Person('金老板','女',20,50)# 实例化另一个人对象
    teddy = Dog('笨笨','teddy',50,10)   # 实例化一个狗对象
    teddy.bite(alex)             # 狗对象向人对象发起技能
    print(alex.hp)              # 打印人对象的属性
    boss_jin.attack(teddy)         # 人对象向狗对象发起技能
    print(teddy.hp)             # 打印狗对象的属性 

    示例二:
    from
    math import pi class Circle: ''' 定义了一个圆形类; 提供计算面积(area)和周长(perimeter)的方法 ''' def __init__(self,radius): self.radius = radius def area(self): return pi * self.radius * self.radius def perimeter(self): return 2 * pi *self.radius circle = Circle(10) #实例化一个圆 area1 = circle.area() #计算圆面积 per1 = circle.perimeter() #计算圆周长 print(area1,per1) #打印圆面积和周长

    类命名空间与对象、实例的命名空间

    创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性

    类有两种属性:静态属性和动态属性
      静态属性就是直接在类中定义的变量
      动态属性就是定义在类中的方法

    其中类的数据属性是共享给所有对象的

    >>>id(egg.role)
    4341594072
    >>>id(Person.role)
    4341594072

    而类的动态属性是绑定到所有对象的

    >>>egg.attack
    <bound method Person.attack of <__main__.Person object at 0x101285860>>
    >>>Person.attack
    <function Person.attack at 0x10127abf8> 

    创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性

      在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常

    小结

    alex.name   #alex 指向我自己的内存空间 在自己的内存空间里找到name
    alex.attack #alex 先找自己的内存空间 再找到类对象指针 再根据类对象指针找到类 再通过类找到attack

    (1)对象的内存空间里: 只存储对象的属性,而不存储方法和静态属性 (2)方法和静态属性都存储在类的内存空间中目的:为了节省内存,让多个对象去共享类中的资源 (3)对象属性是独有的,静态属性和方法是共享的

    使用类的对象可以找到两个东西?
      (1)对象所在内存空间中的储存的属性
      (2)类对象指针所指类中的所有方法和静态属性。

    找寻顺序:

      (1)对象找名字的时候:先找自己内存空间中的,再找类中的。
      (2)对象没有权力修改类中的静态变量和方法
      (3)用类名去操作静态变量。
      (4)类名:实例化对象,调用静态属性,执行方法

     

    面向对象的组合用法

    组合:一个类作为另一个类的对象的属性

    复制代码
     
     示例一:
    class Weapon:
        def prick(self, obj):  # 这是该装备的主动技能,扎死对方
            obj.life_value -= 500  # 假设攻击力是500
    
    class Person:  # 定义一个人类
        role = 'person'  # 人的角色属性都是人
    
        def __init__(self, name):
            self.name = name  # 每一个角色都有自己的昵称;
            self.weapon = Weapon()  # 给角色绑定一个武器;
            
    egg = Person('egon')
    egg.weapon.prick() 
    #egg组合了一个武器的对象,可以直接egg.weapon来使用组合类中的所有方法
    复制代码


    圆环是由两个圆组成的,圆环的面积是外面圆的面积减去内部圆的面积。圆环的周长是内部圆的周长加上外部圆的周长。
    这个时候,我们就首先实现一个圆形类,计算一个圆的周长和面积。然后在"环形类"中组合圆形的实例作为自己的属性来用

    复制代码
     
     示例二:
    from math import pi
    
    class Circle:
        '''
        定义了一个圆形类;
        提供计算面积(area)和周长(perimeter)的方法
        '''
        def __init__(self,radius):
            self.radius = radius
    
        def area(self):
             return pi * self.radius * self.radius
    
        def perimeter(self):
            return 2 * pi *self.radius
    
    
    circle =  Circle(10) #实例化一个圆
    area1 = circle.area() #计算圆面积
    per1 = circle.perimeter() #计算圆周长
    print(area1,per1) #打印圆面积和周长
    
    class Ring:
        '''
        定义了一个圆环类
        提供圆环的面积和周长的方法
        '''
        def __init__(self,radius_outside,radius_inside):
            self.outsid_circle = Circle(radius_outside)
            self.inside_circle = Circle(radius_inside)
    
        def area(self):
            return self.outsid_circle.area() - self.inside_circle.area()
    
        def perimeter(self):
            return  self.outsid_circle.perimeter() + self.inside_circle.perimeter()
    
    
    ring = Ring(10,5) #实例化一个环形
    print(ring.perimeter()) #计算环形的周长
    print(ring.area()) #计算环形的面积
    复制代码

    用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python课程

    复制代码
     
     示例三:
    class BirthDate:
    def __init__(self,year,month,day): self.year=year self.month=month self.day=day class Couse: def __init__(self,name,price,period): self.name=name self.price=price self.period=period class Teacher: def __init__(self,name,gender,birth,course):
            self.name=name 
    self.gender=gender
    self.birth=birth
    self.course=course
        def teach(self): 
    print('teaching')
    p1=Teacher('egon','male', 
    BirthDate('1995','1','27'),
    Couse('python','28000','4 months')
    )

    print(p1.birth.year,p1.birth.month,p1.birth.day)

    print(p1.course.name,p1.course.price,p1.course.period)
    '''
    运行结果:
    1 27
    python 28000 4 months
    '''
    复制代码

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

           

  • 相关阅读:
    我的扑克牌
    oc第二课
    oc入门第一课
    2014年1月3日
    iOS Navigation自定义设置Item
    iOS 在一个TableView内使用不同的Cell
    iOS 获取应用当前定位授权状态
    iOS 8显示应用角标
    Xcode 设置Pch文件
    iOS 8设置CLLocation授权
  • 原文地址:https://www.cnblogs.com/zsdbk/p/9696898.html
Copyright © 2011-2022 走看看