美文网首页
面对对象知识点

面对对象知识点

作者: ALLIN5 | 来源:发表于2018-08-13 18:51 被阅读9次

名词解析

【类】 :是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用;

【对象】:是由类创建出来的一个具体存在,可以直接使用;

【属性】:对对象的特征的描述;特征 <===>属性

【类属性】:类是一个特殊的对象,给类对象定义的特征,不会用于记录具体的类对象特征

【实例】:对象创建后,内存中就有了一个对象的实实在在的存在 ;实例 <===>对象

【实例化】:创建对象的动作;

【实例属性】:就是对象的属性;

【方法】:对对象的行为/动作的描述; 行为 <===>方法

【类方法】:类是一个特殊的对象,给类对象定义的行为动作;

【实例方法】:对象调用的方法

【静态方法】:在开发时,不需要访问实例属性(类属性),也不需要调用实例方法(类方法)时定义的方法

命名规范和语法格式

【类的命名】: 
    命名规范:名词提炼法,用==大驼峰命名法==来命名
    语法格式:class 类名:

【创建(实例)对象】:对象变量=类名();变量引用了对象,对象去调用类中方法

【创建类对象】:class  类名: 
【定义(实例)方法】:def 方法名(self,参数1,参数2……):第一个参数必须要默认传实例对象,一般习惯用self。

【定义类方法】:@classmethod 
               def 类方法名(cls,参数1,参数2…)第一个参数必须要默认传类,一般习惯用cls

【定义静态方法】:@staticmethod 
                 def  静态方法名():参数没有要求。

静态方法:主要是用来放一些方法,方法的逻辑属于类,但是又和类本身没有交互,从而形成了静态方法,主要是让静态方法放在此类的名称空间之内,从而能够更加有组织性。静态方法在类的命名空间之中

访问(调用)的方式

类和对象:类是模版(只有一个),对象是实例(可以有多个),先有类,再有对象;哪一个类创建出来的对象,就拥有哪 个类定义的属性和方法

 self (cls):由哪一个对象调用的方法(类方法),方法内的self(cls)就是哪一个对象(类对象)的引用
 
在类的外部:通过变量名 . 访问实例属性和方法  

<1>通过 类名 . 访问类属性(调用类方法)/ (调用静态方法)

<2>通过对象.类属性访问类属性(此方式不推荐)

[注意]:如果使用对象.类属性 = 值 赋值语句,只会 给对象添加一个属性,而不会影响到类属性的值 

封装方法内部:通过self.访问实例属性(或调用实例方法)
通过 cls. 访问类属性(或调用类方法)

类属性和实例属性的区别

它们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,

实例属性属于对象;实例属性在每个对象中都要保存一份;

类属性属于类;类属性在内存中只保留一份;

例如:

class Province(object):

    country = '中国'  # 类属性
    
    def __init__(self, name):
    
        self.name = name  # 实例属性
        
obj = Province('山东省')  # 创建一个实例对象

print(obj.name)  # 直接访问实例属性

Province.country  # 直接访问类属性

实例方法、静态方法和类方法格式及比较

比较:

相同点:对于所有的方法而言,均属于类,所以 在内存中也只保存一份

不同点:方法调用者不同、调用方法时自动传入的参数不同。

案例:

class Foo(object):
    def __init__(self, name):
        self.name = name
        
    def ord_func(self):
        """ 定义实例方法,至少有一个self参数 """
        # print(self.name)
        print('实例方法')
        
    @classmethod
    def class_func(cls):
        """ 定义类方法,至少有一个cls参数 """
        print('类方法')
        
    @staticmethod
    def static_func():
        """ 定义静态方法 ,无默认参数"""
        print('静态方法')
        
f = Foo("中国")
# 调用实例方法
f.ord_func()
# 调用类方法
Foo.class_func()
# 调用静态方法
Foo.static_func()

私有化、私有属性、私有方法

私有化
    xx: 公有变量
    _x: 单前置下划线,私有化属性或方法,from somemodule import *禁止导入,类对象和子类可以访问
    __xx:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问(名字重整所以访问不到)
    __xx__:双前后下划线,用户名字空间的魔法对象或属性。例如:__init__ , __ 不要自己发明这样的名字
    xx_:单后置下划线,用于避免与Python关键词的冲突
通过name mangling(名字重整(目的就是以防子类意外重写基类的方法或者属性)如:_Class__object)机制就可以访问      
            private了。
            
私有属性:对象 不希望公开的属性
私有方法:对象 不希望公开的方法

定义方式:在 定义属性或方法时,在 属性名或者方法名前 增加 两个下划线,定义的就是 私有 属性或方法
访问方式:访问私有属性和方法的时,在 名称 前面加上 _类名 => _类名__名称

总结:
    父类中属性名为__名字的,子类不继承,子类不能访问;
    如果在子类中向__名字赋值,那么会在子类中定义的一个与父类相同名字的属性;
    _名的变量、函数、类在使用from xxx import *时都不会被导入

封装、继承、多态

封装 :根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中;

多态:
(简言之:子类重写了,调用子类,子类没有重写,调用父类,这就是多态)
    不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度
    多态 可以 增加代码的灵活度
    以 继承 和 重写父类方法 为前提
    是调用方法的技巧,不会影响到类的内部设计
    
继承:
概念:子类 拥有 父类 的所有 方法 和 属性;实现代码的重用,相同的代码不需要重复的编写
继承的传递性:子类 拥有 父类 以及 父类的父类 中封装的所有 属性 和 方法
方法的重写:
<1>覆盖 父类的方法
<2>对父类方法进行 扩展: 在需要的位置使用 super().父类方法 来调用父类方法的执行

[备注] :python3中super后面的括号里 不要加参数,python2必须要加参数,python2 例如:super(Dog,self).bark(color)

父类的 私有属性 和 私有方法:
    子类对象 不能 在自己的方法内部,直接 访问 父类的 私有属性 或 私有方法
    子类对象 可以通过 父类 的 公有方法 间接 访问到 私有属性 或 私有方法
    
多继承
概念:子类 可以拥有 多个父类,并且具有 所有父类 的 属性 和 方法
[备注] 开发时,应该尽量避免这种容易产生混淆的情况!如果父类之间存在同名的属性或者方法,应该 尽量避免 使用多继承
多继承以及MRO顺序

案例如下:

单独调用父类的方法:

class Parent(object):

    def __init__(self, name):
        self.name = name
        
class Son1(Parent):
    def __init__(self, name, age):
        self.age = age
        Parent.__init__(self, name)
        
class Son2(Parent):
    def __init__(self, name, gender):
        self.gender = gender
        Parent.__init__(self, name)
        
class Grandson(Son1, Son2):
    def __init__(self, name, age, gender):
        Son1.__init__(self, name, age)  # 单独调用父类的初始化方法
        Son2.__init__(self, name, gender)

多继承中super调用有所父类的被重写的方法:

class Parent(object):
    def __init__(self, name, *args, **kwargs):  # 为避免多继承报错,使用不定长参数,接受参数
        self.name = name
        
class Son1(Parent):
    def __init__(self, name, age, *args, **kwargs):  # 为避免多继承报错,使用不定长参数,接受参数
        self.age = age
        super().__init__(name, *args, **kwargs)  # 为避免多继承报错,使用不定长参数,接受参数
        
class Son2(Parent):
    def __init__(self, name, gender, *args, **kwargs):  # 为避免多继承报错,使用不定长参数,接受参数
        self.gender = gender
        super().__init__(name, *args, **kwargs)  # 为避免多继承报错,使用不定长参数,接受参数
        
class Grandson(Son1, Son2):
    def __init__(self, name, age, gender):
        # 多继承时,相对于使用类名.__init__方法,要把每个父类全部写一遍
        # 而super只用一句话,执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因
        # super(Grandson, self).__init__(name, age, gender)
        super().__init__(name, age, gender)
        
print(Grandson.__mro__)
gs = Grandson('grandson', 12, '男')
print('姓名:', gs.name)
print('年龄:', gs.age)
print('性别:', gs.gender)

单继承中super

class Parent(object):
    def __init__(self, name):
        self.name = name
        
class Son1(Parent):
    def __init__(self, name, age):
        self.age = age
        super().__init__(name)  # 单继承不能提供全部参数
        
class Grandson(Son1):
    def __init__(self, name, age, gender):
        super().__init__(name, age)  # 单继承不能提供全部参数

单继承多继承使用super方法的总结

super().__init__相对于类名.__init__,在单继承上用法基本无差

但在多继承上有区别:
super方法能保证每个父类的方法只会执行一次,而使用类名的方法会导致方法被执行多次,具体看前面的输出结果

多继承时,使用super方法,对父类的传参数,应该是由于python中super的算法导致的原因,必须把参数全部传递,否则会报错

单继承时,使用super方法,则不能全部传递,只能传父类方法所需的参数,否则会报错

多继承时,相对于使用类名.__init__方法,要把每个父类全部写一遍,而使用super方法,只需写一句话便执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因

新式类与旧式(经典)类
新式类:以 object 为基类的类,推荐使用
经典类:不以 object 为基类的类,不推荐使用

单例

目的 —— 让 类 创建的对象,在系统中 只有 唯一的一个实例
每一次执行 类名() 返回的对象,内存地址是相同的
单例示例
只执行一次初始化工作

相关文章

  • 面对对象知识点

    名词解析 【类】 :是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用; 【对象】:是由类创建出...

  • 大数据技术入门[更新中]

    总结一下目前的知识点,要掌握的知识点 一. 编程语言 1. Java ●. Java基础 面对对象,Java8新...

  • JavaScript | 标准对象

    知识点:基本对象类型,包装对象链接:标准对象 - 廖雪峰的官方网站 知识点:Date对象链接:Date - 廖雪峰...

  • (二)ES6第一节变量(let,const)

    (一) 本节知识点 let命令 块级作用域 const命令 顶层对象的属性 global对象 (二) LET知识点...

  • js常用操作

    base64转blob对象 知识点:Blob Uint8Array blob对象转base64 知识点:FileR...

  • js常用知识点总结-String对象

    js常用知识点总结-String对象 使用String对象: String对象属性: 属性描述constructo...

  • 面对对象:创建对象

    依然在不断强调对象与类的关系,实际上完全能够理解。 语法 基本会了。Java几乎完全面对对象。主函数都在类里面。 ...

  • js常用知识点总结-Number对象

    js常用知识点总结-Number对象 使用Number对象: 对象属性: 属性描述constructor返回对创建...

  • 面对对象

  • 面对对象

    面向对象编程(Object Oriented Programming,缩写为 OOP) 是目前主流的编程范式。它将...

网友评论

      本文标题:面对对象知识点

      本文链接:https://www.haomeiwen.com/subject/xzaubftx.html