zoukankan      html  css  js  c++  java
  • python 3 基础之类和对象的创建、面向对象的三大特性

    面向对象简单理解:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程

    类:对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念——类

      类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在。一个类可以找到多个对象

      如字典就是一类数据结构,字符串是一类数据结构,它们各自都具有相同的特征属性和方法

    对象:某个具体事物的存在,在现实世界看得见摸得着,对象归属于一类;创建一个对象需要依赖于类

    • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。类根据继承可以分为父类和子类
    • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
    • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
    • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
    • 实例变量:定义在方法中的变量,只作用于当前实例的类。
    • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,所以Dog也是一个Animal。(派生类相当于子类,基类相当于父类,只是称呼不同)
    • 实例化:创建一个类的实例,类的具体对象。
    • 方法:类中定义的函数。
    • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法

    1、创建类和对象

      1.1、类

        经典类和新式类,从字面上可以看出一老一新,新的必然包含了更多的功能,是推荐的写法,从写法上区分:如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类

        创建一个类

    # 经典类1
    class Hhh:
        pass
    # 经典类2
    class Jor:
        pass
    # 新式类
    class Fa(object):
        pass

      1.2、创建一个对象

    # 自定义一个狗类(自定义类名一般遵循大驼峰命名)
    class Dog(object):
        # 定义一个方法(实例方法 或 对象方法)
        # 实例方法第一个参数为self(python默认的)
        # 实例方法 下划线 或小驼峰(公司的要求)
        def move(self):
            print('狗会吃骨头')
    # 使用自定义的类创建一个对象
    wangcai = Dog()
    # 调用狗类中的方法(想要使用其类中的方法,要使用这个类创建一个对象 使用对象调用其类里面的方法)
    wangcai.move()

    2、添加对象属性和判别同一个类创建的多个对象是否为同一个对象

      2.1、方法外添加对象属性

     1 # 定义一个Dog类
     2 class Dog(object):
     3     def eat(self):
     4         print('狗吃骨头')
     5     def zuoyong(self):
     6         print('狗会看家')
     7 
     8 # 使用类创建一个对象
     9 wang = Dog()
    10 # 在方法外赋予对象属性
    11 wang.name = '旺财'
    12 wang.age = 4
    13 wang.colour = '白色'
    14 print(wang.name)

      2.2、判别同一个类创建的多个对象是否为同一对象

      python中每创建一个新的对象,需要开辟一个内存空间,占用内存地址,而内存地址是唯一的,以此判断是否为同一个对象,不同对象开辟的内存地址也不同

     1 class Dog(object):
     2     def eat(self):
     3         print('狗吃骨头')
     4 # 使用类创建多个对象
     5 wang = Dog()
     6 wang1 = Dog()
     7 wang2 = Dog()
     8 # 用16进制查看对象的内存地址
     9 print(wang,wang1,wang2)
    10 # 用10进制查看对象的内存地址
    11 print(id(wang))
    12 print(id(wang1))
    13 print(id(wang2))
    14 
    15 ================================
    16 
    17 运行结果:<__main__.Dog object at 0x000002AFC4E21CC8>
    18  <__main__.Dog object at 0x000002AFC4E21D48>
    19  <__main__.Dog object at 0x000002AFC4E21D88>
    20 2953945685192
    21 2953945685320
    22 2953945685384

      运行结果是各不相同,证明同一个类创建的多个对象时唯一的

    3、面向对象的三大特征:封装、继承、多态

      3.1、封装

        顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容;对于面向对象来说,其实就是使用构造方法(__init__)将内容封装到对象中,然后通过对象直接或self间接获取被封装的内容

        封装的意义:

      1. 将属性和方法放到一起做为一个整体,然后通过实例化对象来处理;
      2. 隐藏内部实现细节,只需要和对象及其属性和方法交互就可以了;
      3. 对类的属性和方法增加 访问权限控制

        

        3.1.1、通过 对象.属性 直接调用被封装的内容

    class Hero(object):
        # 构造方法
        def __init__(self, name, hp, atk):
            # 设置属性的值
            self.name = name
            self.hp = hp
            self.atk = atk
    # 创建一个对象
    laosun = Hero('俺老孙',100,10)# 实则就是把'俺老孙',100,10三个数据分别封装到name,hp,atk里
    # 通过对象直接调用
    print(laosun.name)

        3.1.2、通过 对象.方法 间接调用

    class Dog(object):
        # 构造方法
        def __init__(self, new_name, new_age, new_colour="白色"):
            # 给对象的属性赋值
            self.name = new_name
            self.age = new_age
            self.colour = new_colour
        def info(self):
            print("名字:%s" % self.name)
            print("年龄:%d" % self.age)
            print("毛色:%s" % self.colour)
    # 创建一个对象
    wang = Dog('黑狗',4,'黑色')
    # 间接调用
    wang.info()

      3.2、继承

        面向对象的继承和现实中的继承相似,面向对象的继承指的是类的继承,当一个类继承了另外一个类,被继承的类称之为父类,继承的类叫子类

        子类会继承父类的所有方法,属性;对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法

        在继承关系中,如果一个实例的数据类型是某个子类,那它也可以被看做是父类。但是,反过来就不行。

        继承还可以一级一级地继承下来,就好比从爷爷到爸爸、再到儿子这样的关系。而任何类,最终都可以追溯到根类object,这些继承关系看上去就像一颗倒着的树

        3.2.1、单继承

          只是继承一个父类

    # 创建一个类,继承于object
    class Dog(object):
        # 构造方法
        def __init__(self, new_name,):
            # 给对象的属性赋值
            self.name = new_name
        def info(self):
            print("名字:%s" % self.name)
    # 创建一个单继承的子类Heigou,继承类Dog
    class Heigou(Dog): def eat(self): print('黑狗血很贵听说') # 创建一个对象 wang = Dog('黑狗') hei = Heigou('大黑') # 根据对象调用类的方法 wang.info() hei.eat() # 根据对象调用父类的方法 hei.info() ============================================= 结果是成功调用父类的方法

        虽然子类没有定义__init__方法初始化属性,也没有定义实例方法,但是父类有。所以只要创建子类的对象,就默认执行了那个继承过来的__init__方法

        3.2.2、多继承

          子类继承多个父类(Python的类可以继承多个类,Java和C#中则只能继承一个类)

          多继承可以继承多个父类,也继承了所有父类的属性和方法
          注意:如果多个父类中有同名的 属性和方法,则默认使用第一个父类的属性和方法(根据类的魔法属性mro的顺序来查找);多个父类中,不重名的属性和方法,不会有任何影响

    # 创建两个类,继承于object
    class Hero(object):
        def __init__(self, name, hp, atk):
            self.name = name
            self.hp = hp
            self.atk = atk
    class Dog(object):
        def __init__(self, new_name,):
            self.name = new_name
        def info(self):
            print("名字:%s" % self.name)
    # 创建一个多继承的类
    class Heigou(Dog,Hero):
        def eat(self):
            print('黑狗血很贵听说')
    # 创建一个对象
    wang = Dog('黑狗')
    hei = Heigou('大黑')
    # 调用父类的方法
    hei.info()
    # 利用子类的魔法属性__mro__查看属性和方法的查找顺序
    print(Heigou.__mro__)

         当多继承中多个父类都定义了相同的函数(包括函数名,函数内容),子类调用函数时调用的是哪个父类的函数?

        当类是经典类时,会按照深度优先方式查找(子类a继承父类b、c,c又继承了d,当子类调用相同方法时,先查找a是否有此方法,若无,调用b的,若b也无,查看b是否有继承父类,有则 继续查找b的父类 ,没有则开始查找c,c若无,找c的父类,无则继续找父类的父类)

        当类时新式类时,按照广度优先查找(子类a继承父类b、c,c又继承了d,当子类调用相同方法时,先查找a是否有此方法,若无,调用b的,若b也无,先查找a的第二个父类c,若无,继续查找a的父类,此级父类均没有才开始查找父类的父类)

        如下图

     注意:在上述查找过程中,一旦找到,则寻找过程立即中断,转而执行方法,不会再继续找

      

      3.3、多态(同一个对象,多种形态)

         所谓鸭子类型:看着像鸭子,我们就说它是鸭子

        3.3.1、变量的多态

          多态在python中其实是很不容易说明⽩的. 因为我们⼀直在⽤. 只是没有具体的说.

          比如. 我们创建⼀个变量a = 10 , 我们知道此时a是整数类型. 但是我们可以通过程序让a = "alex", 这时, a⼜变成了字符串类型. 这是我们都知道的. 但是, 我要告诉你的是. 这个就是多态性. 同⼀个变量a可以是多种形态

        3.3.2、类的多态

          在说明多态是什么之前,在 Child 类中重写 print_title() 方法:若为male,print boy;若为female,print girl

    class Person(object):
        def __init__(self,name,sex):
            self.name = name
            self.sex = sex
    
        def print_title(self):
            if self.sex == "male":
                print("man")
            elif self.sex == "female":
                print("woman")
    
    class Child(Person):                # Child 继承 Person
        def print_title(self):
            if self.sex == "male":
                print("boy")
            elif self.sex == "female":
                print("girl")
    
    May = Child("May","female")
    Peter = Person("Peter","male")
    
    print(May.name,May.sex,Peter.name,Peter.sex)
    May.print_title()
    Peter.print_title()

      当子类和父类都存在相同的 print_title()方法时,子类的 print_title() 覆盖了父类的 print_title(),在代码运行时,会调用子类的 print_title()

      这样,我们就获得了继承的另一个好处:多态。 

      多态的好处就是,当需要传入更多的子类,例如新增 Teenagers、Grownups 等时,我们只需要继承 Person 类型就可以了,而print_title()方法既可以直接继承,不重写(即使用Person的),也可以重写一个特有的。这就是多态的意思。调用方只管调用,不管细节,而当我们新增一种Person的子类时,只要确保新方法编写正确,而不用管原来的代码。

      用自己的话说多态:子类继承了父类,子类对父类的方法进行了重写,用子类进行创建对象,用对象可以调用子类的方法,也可以调用父类的方法,这就是多态

         

  • 相关阅读:
    DRUPAL-PSA-CORE-2014-005 && CVE-2014-3704 Drupal 7.31 SQL Injection Vulnerability /includes/database/database.inc Analysis
    WDCP(WDlinux Control Panel) mysql/add_user.php、mysql/add_db.php Authentication Loss
    Penetration Testing、Security Testing、Automation Testing
    Tomcat Server Configuration Automation Reinforcement
    Xcon2014 && Geekpwn2014
    phpMyadmin /scripts/setup.php Remote Code Injection && Execution CVE-2009-1151
    Linux System Log Collection、Log Integration、Log Analysis System Building Learning
    The Linux Process Principle,NameSpace, PID、TID、PGID、PPID、SID、TID、TTY
    Windows Management Instrumentation WMI Security Technology Learning
    IIS FTP Server Anonymous Writeable Reinforcement, WEBDAV Anonymous Writeable Reinforcement(undone)
  • 原文地址:https://www.cnblogs.com/will-wu/p/13259898.html
Copyright © 2011-2022 走看看