面向对象编程,类和对象

面向对象编程

什么是面向对象编程

  面向对象编程(OOP)就是创建“对象”。对象是一组相互关联的变量和函数。这些变量通常称为对象的属性,函数
称为对象的行为。这些对象为程序提供了一个更好、更清晰的结构。
  例如,汽车可以是一个对象。如果我们把汽车当作一个对象,那么它的属性就是——颜色、型号、价格、品牌等
等,它的行为/函数是加速、减速、换挡。
  另一个例子——如果我们把狗当作一个对象,那么它的属性就是——它的颜色、品种、名字、体重等,而它的行为/函数是行走、吠叫、玩耍等。
  面向对象编程(Object Oriented Programming-OOP) 是一种解决软件复用的设计和编程方法。 这种方法把软件
系统中相近相似的操作逻辑和操作 应用数据、状态,以类的型式描述出来,以对象实例的形式在软件系统中复用,以
达到提高软件开发效率的作用。

面向过程编程和面向对象编程的区别

面向过程编程

  面向过程编程(POP)的重点在于过程二字。
  面向过程比较好理解,就是按照人们通常的思维方式,在做一件事情的时候,将这件事情划分为多个步
骤,一步一步来做。
  面向过程编程,就是在进行一个项目时,将这个项目分为多个小的步骤,一个步骤就是一个过程,将这些过
程全部组织起来,就形成了完整的项目。
  (C 语言是典型的面向过程编程语言)
  比如,我们可以将我要去上海这件事情分为以下四个步骤:
  1.网上买票
  2.去高铁站
  3.坐高铁去上海
  4.到达上海
  这里的每个步骤相当于一个过程,我们将这些过程封装成函数,然后,从前到后将这些函数组织起来,就完成了我要去上海这件事情。

面向对象编程

  面向对象编程(OOP)的重点在与对象二字,主要的编程思想是围绕对象展开。
  在思考一个项目的时候,将项目中的重要点/关键点都设计成一个个的类,每个类承担着不同的工作,不同
的功能被归纳到不同的类中。然后,由类产生出对象,这些对象之间的相互作用,最终组成了一个完整的项目。
  面向对象编程中的两个非常重要概念是类与对象,类也是代码复用的一种机制。(代码复用机制:可重复使
用,就像南孚电池广告里说的玩具车用过遥控器还没能接着用)

面向对象语言

  Java 语言是完全的面向对象编程语言,因为所有的步骤都在类中进行。

  C++ 语言是半面向对象编程语言,它被称为带类的 C,即支持面向过程编程,又支持面向对象编程。

  Python 语言是一门脚本语言,以简单优雅为设计理念,即可以面向过程编程,也可以面向对象编程,但不
像C++ 语言那样有太多的复杂枯燥的概念,Python 语言更注重实用性。

面向对象编程三大特征

  封装,继承和多态是面向对象的三大特征,这三种特征都是面向对象编程语言自身提供的机制,可以让我们
更方便的进行面向对象程序设计:
  封装:让用户可以访问需要的方法,禁止访问不必要的方法,屏蔽了类内部的复杂性。
  继承:使得子类可以继承父类的代码,也是一种代码复用手段,增强了类与类之间的逻辑结果关系。同时,
继承也是多态的必要条件。
  多态:一个事物(对象)可以表现多种形态,多态是面向对象编程中,一个非常强大的特性。

类和对象

什么是类

  这个问题的直接答案是:类是对象的集合。与原始数据结构不同,类是用户定义的数据结构。它们使代码更
易于管理。
  简单来说就是某一类事物,它们具有相同的属性和行为或者说是方法,在代码中我们将这些行为或者方法定
义成函数。
  类是抽象的。
  例如,我们在说狗时,在没有特指是什么品种的狗,或者没有具体哪一只狗的时候,这个狗就是一个大类,包含了所有的狗,这时狗就是一个类,是抽象的并没有具体到哪只,只是指代狗这一类事物。

什么是对象

  对象的话就是对类的实现,对象是具体的,已刚才狗为例,狗是 一个大类,是抽象的,当我们说这是一条
颜色是黑色,长尾巴,会‘汪汪’叫的小狗时,这个小狗就是对象,它是具体存在的是一个实体。
  这一个过程我们可以看成将一个抽象的类转化成了一个具体的有属性和行为或者说方法的对象,在代码中
我们称这个过程为实例化。

类:抽象的,是一张“手机设计图”。
对象:具体的,是一个“真正的手机实例”。

类的创建

  在python中一个类的创建使用class关键字实现其基本语法格式如下:
  class 类名:
    多个(≥0)类属性...
    多个(≥0)类方法...
  给类起好名字之后,其后要跟有冒号(:),表示告诉 Python 解释器,下面要开始设计类的内部功能
了,也就是编写类属性和类方法。
  例:
    class Student():
      school = '家里蹲大学'
      def eat(self):
          print('吃饭')
  事实上,我们完全可以创建一个没有任何类属性和类方法的类,换句话说,Python 允许创建空类:
  class Empty:
    pass

新式类和旧式类

  # class Hero:  # 经典类(旧式类)定义形式
  # class Hero():

  class Hero(object):  # 新式类定义形式
      def info(self):
          print("英雄各有见,何必问出处。")
  '''
    ①定义类时有2种形式:新式类和经典类,上面代码中的Hero为新式类,前两行注释部分则为经典类;
    ②object 是Python 里所有类的最顶级父类;
    ③类名 的命名规则按照"大驼峰命名法";
    ④info 是一个实例方法,第一个参数一般是self,表示实例对象本身,当然了可以将self换为其它的名字,其作用是一个变量这个变量指向了实例对象
  '''

对象实例化

实例化对象

  实例化基本语法:
    对象名 = 类名()
  当类中构造方法除了self还有别的参数时:
    对象名 = 类名(参数1,参数2,参数3...)

  例:
    class Cat:
    """定义了一个Cat类"""

      #方法
      def eat(self):
          print("猫在吃鱼....")
      def drink(self):
          print("猫正在喝kele.....")
      def introduce(self):
          print("%s的年龄是:%d"%(self.name, self.age))

    #创建一个对象
    tom = Cat()

__init__类构造方法

对象既然有实例方法,是否也可以有自己的属性?
  添加和获取对象的属性
  class Hero(object):
      """定义了一个英雄类,可以移动和攻击"""
      def move(self):
          """实例方法"""
          print("正在前往事发地点...")

      def attack(self):
          """实例方法"""
          print("发出了一招强力的普通攻击...")

  # 实例化了一个英雄对象 泰达米尔
  taidamier = Hero()

  # 给对象添加属性,以及对应的属性值
  taidamier.name = "泰达米尔"  # 姓名
  taidamier.hp = 2600  # 生命值
  taidamier.atk = 450  # 攻击力
  taidamier.armor = 200  # 护甲值

  # 通过.成员选择运算符,获取对象的属性值
  print("英雄 %s 的生命值 :%d" % (taidamier.name, taidamier.hp))
  print("英雄 %s 的攻击力 :%d" % (taidamier.name, taidamier.atk))
  print("英雄 %s 的护甲值 :%d" % (taidamier.name, taidamier.armor))

  # 通过.成员选择运算符,获取对象的实例方法
  taidamier.move()
  taidamier.attack()
  
  结果为:
    英雄 泰达米尔 的生命值 :2600
    英雄 泰达米尔 的攻击力 :450
    英雄 泰达米尔 的护甲值 :200
    正在前往事发地点...
    发出了一招强力的普通攻击...
对象创建并添加属性后,能否在类的实例方法里获取这些属性呢?如果可以的话,应该通过什么方式?
  在方法内通过self获取对象属性
  class Hero(object):
      """定义了一个英雄类,可以移动和攻击"""
      def move(self):
          """实例方法"""
          print("正在前往事发地点...")

      def attack(self):
          """实例方法"""
          print("发出了一招强力的普通攻击...")

      def info(self):
          """在类的实例方法中,通过self获取该对象的属性"""
          print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
          print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
          print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))


  # 实例化了一个英雄对象 泰达米尔
  taidamier = Hero()

  # 给对象添加属性,以及对应的属性值
  taidamier.name = "泰达米尔"  # 姓名
  taidamier.hp = 2600  # 生命值
  taidamier.atk = 450  # 攻击力
  taidamier.armor = 200  # 护甲值

  # 通过.成员选择运算符,获取对象的实例方法
  taidamier.info()  # 只需要调用实例方法info(),即可获取英雄的属性
  taidamier.move()
  taidamier.attack()
  
  执行结果:
    英雄 泰达米尔 的生命值 :2600
    英雄 泰达米尔 的攻击力 :450
    英雄 泰达米尔 的护甲值 :200
    正在前往事发地点...
    发出了一招强力的普通攻击...
init()方法
  创建对象后再去添加属性有点不合适,有没有简单的办法,可以在创建对象的时候,就已经拥有这些属性?

  class Hero(object):
      """定义了一个英雄类,可以移动和攻击"""
      # Python 的类里提供的,两个下划线开始,两个下划线结束的方法,就是魔法方法,__init__()就是一个魔法方法,通常用来做属性初始化 或 赋值 操作。
      # 如果类面没有写__init__方法,Python会自动创建,但是不执行任何操作,
      # 如果为了能够在完成自己想要的功能,可以自己定义__init__方法,
      # 所以一个类里无论自己是否编写__init__方法 一定有__init__方法。

      def __init__(self):
          """ 方法,用来做变量初始化 或 赋值 操作,在类实例化对象的时候,会被自动调用"""
          self.name = "泰达米尔" # 姓名
          self.hp = 2600 # 生命值
          self.atk = 450  # 攻击力
          self.armor = 200  # 护甲值

      def info(self):
          """在类的实例方法中,通过self获取该对象的属性"""
          print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
          print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
          print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))

      def move(self):
          """实例方法"""
          print("正在前往事发地点...")

      def attack(self):
          """实例方法"""
          print("发出了一招强力的普通攻击...")


  # 实例化了一个英雄对象,并自动调用__init__()方法
  taidamier = Hero()

  # 通过.成员选择运算符,获取对象的实例方法
  taidamier.info() # 只需要调用实例方法info(),即可获取英雄的属性
  taidamier.move()
  taidamier.attack()

  执行结果:
    英雄 泰达米尔 的生命值 :2600
    英雄 泰达米尔 的攻击力 :450
    英雄 泰达米尔 的护甲值 :200
    正在前往事发地点...
    发出了一招强力的普通攻击...
有参__init__()
  class Hero(object):
      """定义了一个英雄类,可以移动和攻击"""

      def __init__(self, name, skill, hp, atk, armor):
          """ __init__() 方法,用来做变量初始化 或 赋值 操作"""
          # 英雄名
          self.name = name
          # 技能
          self.skill = skill
          # 生命值:
          self.hp = hp
          # 攻击力
          self.atk = atk
          # 护甲值
          self.armor = armor

      def move(self):
          """实例方法"""
          print("%s 正在前往事发地点..." % self.name)

      def attack(self):
          """实例方法"""
          print("发出了一招强力的%s..." % self.skill)

      def info(self):
          print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
          print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
          print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))


  # 实例化英雄对象时,参数会传递到对象的__init__()方法里
  taidamier = Hero("泰达米尔", "旋风斩", 2600, 450, 200)
  gailun = Hero("盖伦", "大宝剑", 4200, 260, 400)

  # 直接输出对象即为地址
  print(gailun)
  # <__main__.Hero object at 0x0318B100>
  print(taidamier)
  # <__main__.Hero object at 0x0318B0D0>

  # 不同对象的属性值的单独保存
  print(id(taidamier.name))
  print(id(gailun.name))

  # 同一个类的不同对象,实例方法共享
  print(id(taidamier.move()))
  # 泰达米尔 正在前往事发地点...
  # 2045877480
  print(id(gailun.move()))
  # 盖伦 正在前往事发地点...
  # 2045877480
  因为我之前学习的是java,当我看到这个的时候我就会觉得很熟悉,这不就是Java中的构造函数,在java
中有2种构造函数有参和无参。那么我就可以将这个理解为java中的构造函数。

  简单的介绍一下什么是构造函数:
    建立一个对象时,通常最需要立即做的工作是初始化对象,如对数据成员赋初值
    构造函数就是用来在创造对象时初始化对象,为对象数据成员赋初始值
    类的数据成员是不能在类的定义时初始化的
  使用方法:
     class 类名:
         #初始化函数,用来完成一些默认的设定
         def __init__():
            pass
   __init__()方法,在创建一个对象时默认被调用,不需要手动调用
   __init__(self)中,默认有1个参数名字为self,如果在创建对象时传递了2个实参,那__init__(self)
中除了self作为第一个形参外还需要2个形参,例如__init__(self,x,y)
   __init__(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递进去
  例:
    class Cat:
    """定义了一个Cat类"""
      #初始化对象
      def __init__(self, new_name, new_age):
          self.name = new_name
          self.age = new_age

对象的属性取值和方法调用

  属性取值基本语法:
    对象名.属性名
  方法调用基本语法:
    对象名.函数名(如果需要参数则传入参数)
  例:
    class Cat:
        '''定义了一个Cat类'''

        # 初始化对象
        def __init__(self, new_name, new_age):
            self.name = new_name
            self.age = new_age

        # 方法
        def eat(self):
            print("猫在吃鱼....")

        def drink(self):
            print("猫正在喝kele.....")

        def introduce(self):
            print("%s的年龄是:%d" % (self.name, self.age))

    # 创建一个对象
    tom = Cat("汤姆", 40)
    # 获取tom的new_name属性
    print(tom.name)
    # 获取tom的new_age属性
    print(tom.age)
    # 调用方法
    tom.eat()
    tom.drink()
    tom.introduce()
    执行结果:
    汤姆
    40
    猫在吃鱼....
    猫正在喝kele.....
    汤姆的年龄是:40
posted @ 2022-04-06 18:22  春游去动物园  阅读(122)  评论(0编辑  收藏  举报