python基础——8.面向对象


概念

类 实例化 对象 实例
 1.所谓模子就是类 抽象的 能知道有什么属性 有什么技能 但不能知道属性的具体的值
 2.self里边存在字典关系  用self.__dict__来打印验证
 4.过程
    类名() 首先创造一个对象 穿件一个self变量
    调用init方法 雷鸣括号里的参数会被这里接收
    执行init方法
    返回self
 5.对象名能做的事
    查看属性;
    调用方法;
    修改属性;
 6.类名能做的事
    *调用方法 一般不用,需要自己传self参数,用对象调用更省事
    实例化
    调用类中的属性,类属性,静态属性
 7.类名和对象名都能调用__dict__的属性,对象名.__dict__还能修改属性
 8.类中的静态属性可以被类名和对象名调用
 9.对于不可变数据类型来说,类变量最好用类名操作
    用对象名操作可变数据类型,比如列表,会造成类静态变量发生改变
    对于可变数据类型用下标可以对静态变量进行赋值是成立的,修改是共享的
 10.一个类可以没有__init__
 11.函数,类名.方法名,对象名.方法名打印的结果
    
    <类名.方法名 at>
    
 12.import package --- 就是类的实例化的过程
 13.组合:一个对象的属性值是另外一个类的对象
 14.class A               父类 基类 超类
    class A_son(A)        # 父类在儿子类的括号里    子类,派生类
    class A_son(A,B)      可以多个爸爸
    一个类可以被多个类继承
    一个类可以继承多个类    python里独有的
    在python3里所有的类都有父类 没有父类的类都是obecj的子类,叫新式类
    用.__bases__查父类
    super().__init__()
    super(Dog.jin).eat()

三大特性

# 继承
    继承的类是子类,被继承的类是父类.
    子类能利用父类的属性和方法,不用重复编写
    class A:
    class B(A):
# 多态
    python 没有支持多态的机制,天生支持多态
# 封装
    广义上面向对象的封装:代码的保护,面向对象的思想本身就是一种
    只让自己的对象能调用自己类中的方法
    狭义上的封装 --- 面向对象的三大特性之一
    属性和方法都隐藏起来 不让看见
    # 私有方法和私有属性
        __属性名 为私有属性
        用对象名.__dict__可以调到变量,看到的字典格式是_类名__属性名
        所以,用同样方法在类外能调到,但是不能这么干
        在方法中,返回私有属性也能得到结果
        def get_pwd(self):
            return self.__passwd
        在类的外部不能定义私有变量
        在方法名前加双下,同样也看不见了,私有方法.
        对象的私有属性,类中的私有方法,类中的静态私有属性
        父类的私有属性不能被子类调用

    # java 面向对象编程
    # 设计模式 --- 接口
    # 抽象类 python原生支持
    # 接口类 python原生不支持
    from abc import abstractmethod,ABCMeta
    class Payment(metaclass=ABCMeta):   # 元类 默认的元类 type
        @abstractmethod
        def pay(self, money):pass       # 没有实现这个方法
    # 规范:接口类或者抽象类都可以
    # 接口类 默认多继承,接口类中的所有的方法都必须不能实现 -- java演化来的
    # 抽象类 不支持多继承,抽象类中可以有一些代码的实现  -- java


属性和方法

# 属性可以 查看 修改 删除
# 在类内部使用 self.__class attribute设置私有属性
# 可以访问到,不合规调用方式 _类名.__属性名
# 父类的私有属性不能被子类调用,私有方法同样调不到
# 私有属性在类外边无法被定义
# 用到私有属性的场景
  1.隐藏起一个属性,不想让类的外部调用
  2.想保护这个属性不被任意修改
  3.保护这个属性不被子类继承

# 1.类属性:类名和对象名都能调用类属性
# 2.普通属性:类名不能调用普通属性
# 3.私有属性:只能用对象名._类名__类属性 调用
# 4.类方法(@classmethod):类名和方法名都能调用类方法(只涉及静态属性就用)
# 5.普通方法:类名在不加self下可以调用普通方法(不合法)
# 6.静态方法(@staticmethod):类名和方法名都能调,不用实例化(既和对象没关又和类没关就用)
# 7.属性方法(@property):类名不能调用属性方法
# 8.内置方法:内置的类方法和内置的函数之间有着千丝万缕的联系
# 9.对象可以调用类方法和静态方法,一般推荐用类名调用

类的分类

新式类
经典类
关于init:新式类使用super初始化父类,经典类中直接初始化
关于继承:新式类多继承中广度优先,经典类多继承中深度优先

反射没有安全问题

反射对象的属性
hashattr
getattr
setattr
delattr

isinstance(a, A) 对象是否是类的对象

issubclass(B, A) 是否是子类

类里的内置方法

repr
可以把打印原封不动的表现出来 1, "1"
str
一定return一个字符串

object 里有一个__str__,一旦被调用,就返回调用这个方法的对象的内存地址

class A:
    pass
a = A()
print(str(a))

每当打印一个对象的时候,其实就是调用__str__方法,返回回来。

%s str() 直接打印 实际都是执行的__str__方法

__repr__是__str__备胎,但是反过来不行

str(obj)的时候,实际上是内部调用了obj.__str__方法,如果str方法有,那么它返回的必定是一个str

如果没有__str__ 会找本类中__repr__方法,再没有再找父__str__

引用计数?

call 一个对象加上()执行了这个方法