• No.009-Python-学习之路-Day6-面向对象的特性及语法


    面向对象介绍

    何为编程?

    程序员按照特定的语法数据结构算法组织代码,以此来告诉计算机如何执行任务的过程;

    编程范式[Programming paradigm]

    从不同编程方式中归纳总结出来的编程方式类别,包含面向过程面向对象函数式编程等;

    面向过程[Procedure Oriented]

    通过一组指令,一步步告诉电脑怎么做,依赖Procedure[过程];

    核心思想:大问题->小问题->更小的问题->(可以在一个小范围内解决);

    问       题:从上到下,逐步依赖,改一个位置,相关依赖均要修改;

    使用场景:面向过程比较适合简单脚本,一次性任务等场景使用,效率较高;

    面向对象[OOP-Object Oriented Programming]

    通过类与对象创建各种模型来实现对真实世界的描述;世界万物,皆可分类;世界万物,皆为对象;

    只要是对象,就肯定属于某个品类;

    只要是对象,就肯定有属性<静态属性,动态属性>;

    在描述现实世界时,需要按照现实世界的规则来,所以需要搭建一个框架,才能够对某个事物进行描述;

    优       势:易维护,易扩展,编程效率高,使别人更易理解,是团队开发变得从容;

    语法

    包含:属性、方法、构造函数、析构函数、私有方法、私有属性、类变量、实例变量。

    class Dog: # 定义一个类 Dog 类名
        n = 123 # 类变量<存在类的内存中>
                # 类变量,所有实例公用的属性,可以修改,节省开销
        name = "Class name"
        name_list = ['11', '22', '33']
        # 在实例化时,需要赋予的属性
        # 构造函数:
         # 作用:在实例化时,做一些类的初始化的工作<实例赋名字,传参数之类>
        def __init__(dog_var, name): # dog_var用来接收实例名,如dog1, dog2,dog3
            dog_var.name = name # dog_var.name属于实例变量<静态属性>,作用域是实例本身
                                # 实例变量用来描述类的不同实例的不同属性
            dog_var.__owner = "Bruce" # 私有属性
    # 私有方法同理,def __siyou(self): pass # 类的方法,功能<动态属性> def bulk(dog_var1): # dog_var1也是用来接收实例名,如dog1,dog2,dog3 print("%s Wang wang wang!!!" % dog_var1.name) def get_owner(self): print(self.__owner) def __del__(self): # 析构函数 #print("%s was dead!!" % self.name) #print("I miss you %s." % self.name) pass # 生成对象dog1-3 # 实例化(初始化一个类,造了一个对象),把一个类变为一个实例的过程; # 对象又称为Dog类的一个实例 dog1 = Dog('Xilou') dog2 = Dog("QiuQiu") # 生成了一具体的狗狗 dog3 = Dog("Buck") # 让狗叫 dog1.bulk() # 等价于Dog.bulk(dog1) Dog.bulk(dog1) # 等价于dog1.bulk() del dog1 # 删除实例<摘门牌号>,删除时调用析构函数__del__(self): dog2.bulk() dog3.bulk() #### 类变量与实例变量的介绍与区别 print(Dog.n) # 类变量=>未实例化即可调用 print(Dog.name) dog4 = Dog("Mengmeng") print(dog4.n) print(dog4.name) # 变量先找实例本身,如果没有则找类变量的; dog5 = Dog("Doudou") dog5.name = "豆豆" # 实例属性可以修改 dog5.kind = 'little dog' # 为实例新增属性 del dog5.name # 删除实例属性 print(dog5.name, dog5.kind) dog4.n = 10 # 由结果推断,实例类变量的修改,实际是在实例内存内新建dog4.n=10这个变量; dog6 = Dog("NianNian") print(dog4.n, dog5.n, dog6.n) # dog4实例的类变量变更,dog5及dog6未做变更; dog4.name_list.append('55') print(dog4.name_list) dog4.name_list = [333] dog4.name_list.append(222) print(dog4.name_list) Dog.n = "类修改" # # dog4不受影响,原因之前修改在实例中新建了同名的实例变量 # dog5及dog6调用类变量,所以修改类变量,返回值跟着修改 print(dog4.n, dog5.n, dog6.n) print(dog5.name_list) dog5.get_owner() ##### # 析构函数:在实例释放、销毁的时候自动执行的,通常用于做一些收尾工作<关闭一些数据库链接,打开的临时文件等>; # python判断变量是否在用-->变量名在则在用,变量不在则不再用-->不在用则从内存中回收; ##### # 私有方法,私有属性:外部<实例之外>无法访问,只能内部访问<实例内部的方法>; # 用于类的封装; dog10 = Dog('XiLou Lee') print(dog10.__owner) # 直接访问无法访问 dog10.get_owner() # 调用方法访问 #####

     实例的生成过程

    特性

    类[class]

    即分类,对一类拥有相同属性<静态属性,动态属性-即方法>的对象的抽象;

    对象[object]

    即是一个类实例化后的实例;类是对象的抽象,对象是类的特例;

    封装[Encapsulation]

    封装就是把抽象的数据和对数据进行的操作封装在一起,数据被保存在内部,程序的其他部分只有通过授权的操作(成员方法等)才能对数据进行操作;

    继承[Interitance]

    一个类可以派生出特殊的子类,则原有类为父类,而父类的属性及方法可以被子类继承;

    # 父类-人类
    class People: #经典类
    #标准写法 class People(object): # 新式类<多继承的方法变了>
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def eat(self):
            print("%s is eating." % self.name)
    
        def sleep(self):
            print("%s is sleeping" % self.name)
    
        def talk(self):
            print("%s is talking" % self.name)
    
    # 子类1-男人
    class Man(People):
    
        def __init__(self, name, age, size): # 对构造函数进行重构,实例化时,实际的调用
            People.__init__(self,name, age) # 所以,需要获取将父类构造函数的变量 # 并调用父类的构造函数
            # People.是经典类的写法
            # super(Man, self).__init__(name.age) 等价于上面的调用,作用在父类<People>的名称变更时,不需要更改
            # super是新式类的写法,用的更多;
    
            self.size = size
    
        def piao(self):
            print("%s is piaoing....20s...done." %self.name)
    
        def sleep(self):
            People.sleep(self)
            print("%s is shout." % self.name)
    
        def get_size(self):
            print("%s's size is %s." % (self.name, self.size))
    # 子类2-女人
    class Woman(People):
    
        def get_birth(self):
            print("%s can born a baby...." % self.name)
    
    m1 = Man("Bruce", "22", "200")
    m1.eat() # 继承父类的方法
    m1.piao() # 子类新增的方法
    m1.sleep() # 重构父类的方法
    m1.get_size()
    
    w1 = Woman("Ling", '35')
    w1.get_birth()
    
    #####
    # 新式类及经典类,对于我们有影响的,主要体现在继承上;
    #####

     多继承方式:

    # 父类-人类
    class People(object):
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
            self.friends = []
    
        def eat(self):
            print("%s is eating." % self.name)
    
        def sleep(self):
            print("%s is sleeping" % self.name)
    
        def talk(self):
            print("%s is talking" % self.name)
    
    # 父类-关系
    class Relation(object):
        def make_friends(self, obj):
            print('%s is making friends with %s' %(self.name, obj.name))
            self.friends.append(obj)
    
    # 子类1-男人
    class Man(People, Relation):
    
        def __init__(self, name, age, size):
            super(Man, self).__init__(name, age)
            self.size = size
    
        def piao(self):
            print("%s is piaoing....20s...done." %self.name)
    
        def sleep(self):
            People.sleep(self)
            print("%s is shout." % self.name)
    
        def get_size(self):
            print("%s's size is %s." % (self.name, self.size))
    
    # 子类2-女人
    class Woman(People, Relation): # 多继承顺序是从左到右
    
        def get_birth(self):
            print("%s can born a baby...." % self.name)
    
    
    m1 = Man("Bruce", 22, 2000)
    w1 = Woman("Lee", 23)
    
    m1.make_friends(w1) # 为什么传obj,人只能跟人交朋友,不能和字符串呀!!!!
    print(m1.friends) # m1的friends列表中有w1这个人
    print(m1.friends[0].name) # 获取m1朋友w1的名字,如果用字符串,就没有联系了呀;
    #####
    # 新式类及经典类,对于我们有影响的,主要体现在继承的多继承这方面;
    # 为什么要进行多继承:
        # 因为一样东西可能同时属于两个类;或者拥有该种特质;
    # 多继承顺序是从左到右,构造函数也是这么执行的;(广度优先<新式类>),深度优先<经典类&Python2>;

    #####

    多态[Polymorphism]

    即,一个接口多种实现;

    指一个引用在不同情况下的多种状态;

    指通过指向父类的指针,来调用在不同子类中实现的方法;

    def animal_bulk(obj): # 统一的一个接口
        obj.bulk()
    
    class Animal(object):
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        @staticmethod
        def all_bulk(obj): # 统一的一个接口
            obj.bulk()
    
    class Dog(Animal):
    
        def __init__(self, name, age):
            super().__init__(name, age)
    
        def bulk(self):
            print("Woof Woof!!")
    
    class Goat(Animal):
    
        def __init__(self, name, age):
            super().__init__(name, age)
    
        def bulk(self):
            print("Mian......")
    
    
    dog1 = Dog("QiuQiu", 12)
    goat1 = Goat("ShanDa", 2)
    
    # 静态类方法写法
    Animal.all_bulk(dog1)
    Animal.all_bulk(goat1)
    # 类外函数调用
    animal_bulk(dog1)
    animal_bulk(goat1)

     特性总结:

    封装是为了隐藏实现细节,使得代码模块化;

    继承可以扩展已存在在的代码模块(类);

    封装和继承均为了一个目的:代码的重用;

    而多态为了实现另外一个目的-接口重用,为了类在继承和派生的时候,保证使用‘家谱’中任一类的实例和某一属性时的正确调用;

    end

  • 相关阅读:
    c/cpp枚举练习
    数据类型的标识
    引用变量
    cocos2dx 3.3 笔记
    希望获取到页面中所有的checkbox怎么做?
    如何判断某变量是否为数组数据类型?
    驼峰函数写法
    trim()函数
    js 获取页面可视区域宽高
    全屏滚动插件
  • 原文地址:https://www.cnblogs.com/FcBlogPythonLinux/p/12186747.html
Copyright © 2020-2023  润新知