面向对象

面向对象概念

语言的分类

面向机器

抽象成机器指令,机器容易理解的

代表:汇编语言

面向过程

做一件事,第一步该干嘛,第二布该干嘛,如果出现情况A怎么办,否则怎样

代表:c语言

面向对象

随着计算机需要解决的问题规模扩大,情况越来越复杂,需要很多人协作,面向过程不太合适了。

代表:c++,java,python

面向对象

什么是面向对象呢?

一种认识世界,分析世界的方法论,将万事万物抽象为各种对象。

类calss

类是抽象的概念,是万事万物的抽象,是一类事物的共同特征集合。用计算机语言来描述类,是属性和方法的集合。

对象instance,object

对象是类的具体体现,是一个实体。

举例:

你吃鱼,你就是对象,鱼也是对象,吃就是动作

你是具体的人,是具体的对象,你属于人类,人类是一个抽象的概念,是无数具体的人的个体的抽象,

鱼也是具体对象,就是你吃的这条鱼,这条鱼属于鱼类,鱼类是无数的鱼抽象出来的概念。

吃是动作,很多动物都有具体的动作,人类和鱼都属于动物,而动物也是抽象的概念,是动物都有吃的动作,但吃法不同。

你驾驶汽车,车就是车类的具体实例(对象),驾驶这个动作是人类具有的,鱼没有

属性:他是对象状态的抽象,用数据结构来描述。

操作:他是对象行为的抽象,用操作名和实现该操作的方法来描述。

每个人都是人类的一个单独的实例,都有自己的属性,名字,身高,体重等,这些信息是个人的属性,但是这些信息不能保存在人类中,因为他是抽象的概念,不能保留具体的值。

而人类的实例,是具体的人,它可以存储这些具体的属性,而且可以不同的人有不同的属性。

哲学

一切皆对象

对象是数据和操作的封装

对象是独立的,但是对象之间可以相互作用

目前oop是最接近人类认知的编程范式

面向对象3要素

1,封装

组装:将数据和操作组装到一起。

隐藏数据:对外只暴露出一些接口,通过接口访问对象,比如驾驶汽车,不需要了解汽车的结构,只需要知道怎么驾驶就行了

2.继承

多复用,继承来的就不用自己写了

多继承少修改,ocp(open-closed principle),使用继承来改变,来体现个性

3.多态

面向对象编程最灵活的地方,动态绑定

人类就是封装

人类继承自动物类,孩子继承父母特征,分为单一继承,多继承

多态,继承自动物的人类,猫类的操作‘吃’不同。

python的类

定义

class ClassName:
	pass

1.必须使用class关键字

2.类名必须用大驼峰,本质上就是一个标识符

3.类定义完成后,就产生了一个类对象,绑定到标识符ClassName上

距离

class MyClass:
	'''a example class'''
    x = 'abc'#类属性
    
    def showme(self):#方法,也是类属性
        return __name__
    
print(MyClass)
print(MyClass.showme)
print(MyClass.__doc__)

类对象及类属性

类对象,类的定义执行后会生成一个类对象

类属性,类定义中的变量和类中定义的方法都是类属性

类变量,上例中x是类MyClass的变量

MyClass 中,x,都是类的属性,doc也是类的特殊属性

showme方法也是类的属性,如同是人类的方法,但是每一个具体的人才能吃东西,也就是是人的实例才能调用的方法。

showme是方法method,本质上就是普通的函数对象function,他一般要求至少有一个参数,第一个形式参数可以是self,(self只是个惯例标识符,可以换),这个参数就留给了self。

self指代当前实例本身

实例化

a = MyClass()

每次实例化得到的实例,都是不同的,python类实例化时会调用实例化new方法,之后调用init方法(构造器),结束时调用del方法(析构器),如果没有定义会在实例化后隐式调用,这能让我们在生成或销毁实例时可以做很多事

init方法
def __init__(self):
	print(self.__class__)

init方法第一参必须为self,因为当配置实例时会调用init,所以此时实例时有的,那么如何把实例给ini

呢,这里就用到了实例绑定,self称为实例变量

注意:init不能有返回值,也就是只能return None,否则会报错

实例变量和类变量

实例变量是每一个实例自己的变量,独有的;类变量是类的变量,是类的所有实例共享的属性和方法

__name__       | 对象名
__class__      | 对象的类型
__dict__       | 对象的属性字典
__qualname__   | 类的限定名

类方法和静态方法

类方法
class A:
    
    @classmethod#该装饰器装饰后,函数的第一参注入类,所以写成cls
    def b(cls):
        pass
静态方法
class A:
    
    @staticmethod#该装饰器装饰后,函数的第一参不注入
    def b(x, y):
        return x + y
普通方法
class Adef b(self):
		print(self.__dict__)

访问控制

class A:
    
    def b(self,pswd = 111):
        self.pswd = pswd
        
    def chpswd(self,num):
        self.pswd = num
    
    
tom = A()
tom.chpswd(123)
tom.pswd = 100
print(tom.pswd)

上例本来是想通过方法控制属性,但是由于属性在外部可以访问,或者说可见,就可以绕过方法直接修改属性。

python提供了私有属性可以解决问题。

私有属性

使用双下划线开头的属性名,就是私有属性,私有属性只能在class中使用

class A:
    
    def b(self,pswd = 111):
        self.__pswd = pswd#私有属性
        
    def chpswd(self,num):
        self.__pswd = num

tom = A()
tom.chpswd(123)#修改成功
tom.__dict__#__pswd被改名为_A__pswd,’_类名‘+‘原属性名’
tom.__pswd#报属性错误
tom.__pswd = 100#新曾一个属性

私有成员的总结
在Python中使用_单下划线或者_双 下划线来标识一一个成员被保护或者被私有化隐藏起来,但是,不管使用什么样的访问控制,都不能真正的阻止用户修改类的成员。Python中没有绝对的安全的保护成员或者私有成员。

因此,前导的下划线只是-种警告或者提醒,请遵守这个约定。除非真有必要,不要修改或者使用保护成员或者私有成员,更不要修改它们。

猴子补丁(Monkey Patch)

可以通过修改或者替换类的成员。使用者调用的方式没有改变,但是,类提供的功能可能已经改变了。

在运行时,对属性、方法、函数等进行动态替换。
其目的往往是为了通过替换、修改来增强、扩展原有代码的能力。
黑魔法,慎用。

属性装饰器

一般好的设计是: 把实例的某些属性保护起来,不让外部直接访问,外部使用getter读取属性和setter方法设置属

class Person:
    def __init__(self,name,age):
        self.name = name
        self.__age = age
        
    @property
    def age(self):#gatage():
        return self.__age
        
    @age.setter
    def age(self,num):#setage():
        self.__age = num
        
    @age.deleter
    def age(self):#delage():
        print('del')
        del self.__age
        
    #age = property(getage,setage,delage,'注释')

对象的销毁

class Person:
    def __init__(self,name,age):
        self.name = name
        self.__age = age
        print(self.name,'+++++++++++++',id(self))
    def __del__(self):
        print(self.name,'-------------',id(self))
        
j = Person('tom1',108)
j = Person('tom2',108)
j = Person('tom3',108)
# tom1 +++++++++++++ 2361270826376
# tom3 ------------- 2361271282568
# tom2 +++++++++++++ 2361269029640
# tom1 ------------- 2361270826376
# tom3 +++++++++++++ 2361271282568
# tom2 ------------- 2361269029640

j = Person(‘tom1’,108)
j = Person(‘tom2’,108)
j = Person(‘tom3’,108)

tom1 +++++++++++++ 2361270826376

tom3 ------------- 2361271282568

tom2 +++++++++++++ 2361269029640

tom1 ------------- 2361270826376

tom3 +++++++++++++ 2361271282568

tom2 ------------- 2361269029640


实例引用计数为零后,会调用del方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值