面向对象总结

一、类

  类的概念:具有相同属性和技能的一类事物

  一、静态属性

    变量:使用类名调用

# 引用静态变量
# 1.类名.__dict__['静态变量名'] 可以查看,但是不能删改
# 2.类名.静态变量名 直接就可以访问,可以删改
# 删除一个静态变量 del 类名.静态变量名
class A:role = 'sb'
print(A.__dict__)   # {'__dict__': <attribute '__dict__' of 'A' objects>, '__module__': '__main__', 'role': 'sb', '__doc__': None, '__weakref__': <attribute '__weakref__' of 'A' objects>}
print(A.__dict__['role'])   # sb
print(A.role)   # sb
del A.role
print(A.__dict__)   # {'__dict__': <attribute '__dict__' of 'A' objects>, '__module__': '__main__', '__doc__': None, '__weakref__': <attribute '__weakref__' of 'A' objects>}

  二、动态属性

    1、内置方法

      __init__

    2、普通方法

      1、自带一个self参数

      2、使用对象调用

    3、类方法

      1、@classmethod装饰的

      2、默认传cls参数

      3、使用类名可以直接调用

    4、静态方法

      1、@staticmethod装饰的

      2、没有默认参数

      3、使用类名调用,其他细节和函数相同

    5、属性方法

      1、@property装饰

        1)@funcname.setter

        2)@funcname.deleter

      2、将一个方法伪装成属性

# 引用静态变量
# 1.类名.__dict__['静态变量名'] 可以查看,但是不能删改
# 2.类名.静态变量名 直接就可以访问,可以删改
# 删除一个静态变量 del 类名.静态变量名
class A:role = 'sb'
print(A.__dict__)   # {'__dict__': <attribute '__dict__' of 'A' objects>, '__module__': '__main__', 'role': 'sb', '__doc__': None, '__weakref__': <attribute '__weakref__' of 'A' objects>}
print(A.__dict__['role'])   # sb
print(A.role)   # sb
del A.role
print(A.__dict__)   # {'__dict__': <attribute '__dict__' of 'A' objects>, '__module__': '__main__', '__doc__': None, '__weakref__': <attribute '__weakref__' of 'A' objects>}


# 引用动态变量
# 1.类名.方法名  查看这个方法的内存地址
# 1.类名.方法名(实参)  调用了这个方法,必须传一个实参,这个实参传给了self
class A:
    cat = 'bosi'
    def __init__(self,name,sex):    # 内置方法
        self.name = name
        self.sex = sex
    def action(self):   # 普通方法
        return '%s去泰国做手术,现在性别%s,现在被%s咬了' % (self.name,self.sex,self.cat)
    @classmethod
    def attack(cls,dog):    # 类方法
        cls.cat = dog
    @staticmethod   # 静态方法
    def box(father):
        return '张凯峻变成这样%s的错误' % father
person = A('张凯峻','')
ret = person.action()
print(ret)  # 张凯峻去泰国做手术,现在性别女,现在被bosi咬了
A.attack('taidi')    #
print(A.cat)    # taidi
print(A.box(''))

# 方法伪装成的属性的修改
class Goods:
    def __init__(self,name,origin_price,discount):
        self.name = name
        self.__price = origin_price
        self.__discount = discount

    @property
    def price(self):
        return self.__price * self.__discount
    @price.setter
    def price(self,new_price):
        if type(new_price) is int or type(new_price) is float:
            self.__price = new_price
apple = Goods('apple',5,0.8)
print(apple.price)  # 4.0
# 修改苹果的原价
apple.price = 8
print(apple.price)  # 6.4

# 方法伪装成的属性的删除
class Person:
    def __init__(self,n):
        self.__name = n  # 私有的属性了
    @property            # 重要程度 ****
    def name(self):
        return self.__name
    @name.deleter
    def name(self):
        print('name 被删除了')  # 只打出print结果,不是删除私有属性
    # @name.deleter         # 重要程度*
    # def name(self):
    #     del self.__name     # 执行删除

p = Person('alex')
print(p.name)   # alex
del p.name  # 只是执行了被@name.deleter装饰的函数  name 被删除了

# @property --> func     将方法伪装成属性,只观看的事儿
# @func.setter --> func  对伪装的属性进行赋值的时候调用这个方法 一般情况下用来做修改
# @func.deleter --> func 在执行del 对象.func的时候调用这个方法 一般情况下用来做删除 基本不用

# 将一些需要随着一部分属性的变化而变化的值的计算过程 从方法 伪装成属性
# 将私有的属性保护起来,让修改的部分增加一些约束,来提高程序的稳定性和数据的安全性

  三、私有的属性

    动态属性和静态属性都可以定义为私有的

    运用环境:1、当一个方法不想被子类继承的时候

         2、有些属性或者方法不希望从外部调用,只想提供给内部的方法使用

# 定义一个私有的名字 : 就是在私有的名气前面加两条下划线 __N = 'aaa'
# 所谓私有,就是不能在类的外面去引用它
class A:
    __N = 'aaa'  # 静态变量
    def func(self):
        print(A.__N)  # 在类的内部使用正常

a = A()
a.func()    # aaa
# print(A.__N)   # 在类的外部直接使用 报错

class A:
    __N = 'aaa'  # 静态变量
    def func(self):
        print(A.__N)  # 在类的内部使用正常

print(A.__dict__)   # {'func': <function A.func at 0x000001C95CDF1840>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'A' objects>, '_A__N': 'aaa', '__dict__': <attribute '__dict__' of 'A' objects>, '__doc__': None}
print(A._A__N)   # python就是把__名字当成私有的语法 aaa

# 一个私有的名字 在存储的过程中仍然会出现在A.__dict__中,所以我们仍然可以调用到。
# python对其的名字进行了修改: _类名__名字
# 只不过在类的外部调用 :需要“_类名__名字”去使用
# 在类的内部可以正常的使用名字
# _A__N
# 在类内 只要你的代码遇到__名字,就会被python解释器自动的转换成_类名__名字

# 私有的属性
class B:
    def __init__(self,name):
        self.__name = name
    def func(self):
        print('in func : %s'%self.__name)
b = B('alex')
print(b._B__name)   # alex
b.func()    # in func : alex

# 私有的方法
class C:
    def __wahaha(self):
        print('wahaha')
    def ADCa(self):
        self.__wahaha()
c = C()
c._C__wahaha()  # wahaha
c.ADCa()    # wahaha

# 在类中,静态属性,方法,对象属性都可以变成私有的,只需要在这些名字之前加上__

# class D:
#     def __func(self):      # '_D__func'
#         print('in func')
#
# class E(D):
#     def __init__(self):
#         self.__func()      # '_E__func'
# e = E()
# 私有的名字不能被子类继承

二、对象

  对象的概念:就是对一个类的具体的描述

# 在类的内部 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):
        print('%s发起了一次攻击'%self.name)

alex = Person('a_sb','不详',1,5)
print(alex.__dict__['sex']) # 不详
Person.attack(alex) # a_sb发起了一次攻击


class F:
    def ADCa(self):
        self.__name = 'alex'   # _F__name

f = F()
f.ADCa()
print(f._F__name)   # alex

三、命名空间

  一、类的命名空间

    1、内置属性

      __dict__ : 类的属性(包含一个字典,由类的数据属性组成)

      __doc__ :类的文档字符串

      __name__: 类名

      __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)

      __bases__ : 类的所有父类构成元素(包含了以个由所有父类组成的元组)

    2、静态属性

    3、动态属性

    4、指针

      指向父类

# 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):
#         self.hobby = 'girl'
#         print('%s发起了一次攻击'%self.name)
#
# alex = Person('a_sb','不详',1,5)
# alex.attack()   # Person.attack(alex)
# alex.age = 81
# # alex --> Person
# # Person实例化了alex
# print(alex.__dict__)

# alex.name   #alex 指向我自己的内存空间 在自己的内存空间里找到name
# alex.attack #alex 先找自己的内存空间 再找到类对象指针 再根据类对象指针找到类 再通过类找到attack
# 对象的内存空间里: 只存储对象的属性,而不存储方法和静态属性
# 方法和静态属性都存储在类的内存空间中
# 为了节省内存,让多个对象去共享类中的资源

  二、对象的命名空间

四、实例化及面向对象的使用

  一、实例化

    实例化过程:

      1.创造一个实例,将会作为一个实际参数 # python

      2.自动触发一个__init__的方法,并且把实例以参数的形式传递给__init__方法中的self形参

      3.执行完__init__方法之后,会将self自动返回给alex

    __init__方法 :初始化方法,给一个对象添加一些基础属性的方法,一般情况下是针对self的赋值

  二、组合

    定义:一个类的对象作为另一个类对象的属性

    为什么会用组合 :独立的对象不能发挥他的作用,必须依赖一个对象

    对象名.属性名表示另一个对象

  三、交互

    1、对象可以赋值

    2、对象可以作为一个方法的参数

    3、对象可以作为方法的返回值

    4、对象可以作为一个容器类型的元素

# 组合
# 老师
# 姓名 年龄 性别 班级 : s11

# 班级
# 班级名 班级人数 科目 性质

class Clas:
    def __init__(self,name,num,course,type):
        self.name = name
        self.num = num
        self.course = course
        self.type = type

class Teacher:
    def __init__(self,name,sex,age,py11):
        self.name = name
        self.sex = sex
        self.age = age
        self.cls = py11

py11 = Clas('超级无敌s11',89,'python','脱产全栈')
print(py11.course)

boss_jin = Teacher('太白','',40,py11)
print(py11.course)          # 11期的课程
print(boss_jin.cls.course)  # 金老板所带的班级的课程
print(boss_jin.cls.name)  # 金老板所带的班级的课程
print(boss_jin.cls.num)  # 金老板所带的班级的课程
# 交互
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) #打印圆面积和周长

五、面向对象三大特性

  一、封装

    

  二、继承

    

  三、多态

原文地址:https://www.cnblogs.com/qiujie/p/8987796.html