python_days7_面向对象

面向对象编程

面向对象(Object oriented Programming,OOP)编程的思想主要是针对大型软件设计而来的。面向对象编程使程序的扩展属性更强、可读性更好,使的编程可以像搭积本一性简单。
面向对象编程将数据和操作数据相关的方法封装到对象中,组织代码和数据的方式更加接近人的思维,从而大大提高了编程的效率
Python完全采用了面向对象的思想,是真正面向对象的编程语言,完全支持面向对象的基本功能,例如:继承、多态、封装等。
Python 中,—切皆对象
注:Python支持面向过程、面向对象、函数式编程等多种编程范式。

面向对象和面向过程区别

  • 面向过程(Procedure Oriented)思维
    面向过程编程更加关注的是程序的逻辑流程,是一种执行者思维,适合编写小规模程序。
    面向过程思想思考问题时,我们首先思考怎么按步骤实现?并将步骤对应成方法, 一步一步,最终完成。这个适合简单任务,不需要过多协作的情下.比如如何开车?我们很容易就列出实现步骤
    1.发动车2.挂挡3踩油门4.出发
    面向过程适合简单不需要协作的事务。但是当我们思考比较复杂的问题,比如“如何造车”就会发现列出1234这样的步骤,是不可能的。那是因为,造车太复杂,需要很多协作才能完成。此时面向对象思想就应运而生了,
  • 面向对象(Object Oriented)思维
    面向对象更加以关注的是“事件中对象之间的关系”是一种“设计者”思维.适合编写大规模的程序。
    画面向对象(Object)思想更契合人的思维模式。找们首先思考的是“怎么设计个事物?”比如思考造车,我们会先思考“车怎么设计?”,而不是“怎么按步骤造车的问题”.这就是思维方式的转变。
    面向对象方式思考造车发现车由如下对象组成:
    1.轮胎
    2.发动机
    3.车壳
    4.座椅
    5.挡风玻璃
    为了便于协作,我们找轮胎厂完成制造轮胎的步骤,发动机厂完成制造发动机的步骤;这样,发现大家可以同时进行车的制造,最终进行组装,大大提高了效率。但是,具体到轮胎厂的一个流水线操作,仍然是有步骤的,还是离不开面向过程思想!
    因此,面向对象可以帮助我们从宏观上把握、从整体上分析整个系统。但是,具体实现部分的微观操作(就是一个个方法),仍然期要面向过程的思路去处理。
    面向对象思考方式
    遇到复杂问题,先从问题中找名词(面向过程更多的是找动词),然后确立这些名词哪些可以作为类,再根据问题需求确定类的属性和方法,确定类之间的关系。

面向对象和面向程的总结

  • 都是解决问题的思维方式,都是代码组织的方式。
  • 解决简单问题可以使用面向过程
  • 解决复杂问题:宏观上使用面向对象把握,微观处理上仍然是面向过程。

对象的进化

随着编程面临的问题越来越复杂,编程语言本身也在进化,从主要处理简单数据开始,随着数据变多进化“数组”;数据类型变复杂,进化出了“结构体”;处理数据的方式和逻辑变复杂,进化出了“对象"
1.简单数据
像30.40,50.4等这些数字,可以看做是简单数据。最初的计算机编程,都是像这样的数字。
2.数组
将同类型的数据放到一起。比如:整数数组[2,3,4],字符串数组:[‘a’,‘b’,‘v’]
3.结构体.
将不同类型的数据放到一起,是C语言中的数据结构

struct resume{
    int age;
    char name[10]
    double salary
};

4.对象
将不同类型的数据、方法(函数)放到一起

class Student:
    school ="syxx" #类属性
    count=0     #类属性

    def __init__ (self,name,score):
        self.name = name #实例属性
        self.score=score
        Student.count= Student.count+1
    def say_Score(self):#实例方法
print("我的学校是:" Student.school)
print(self.name,'的分数是:',self.score)

类的定义

把对象比作饼干。类就是制造饼干的模具
我们通过类定义数据类型的属性(数据)和方法(行为),即是:类将行为和状态打包在一起
在这里插入图片描述
对象是类的具体实体;一般称为“类的实例”。类看做”饼干模具“,对象就是根据这个"模具”造出的"饼干”。
从—个类创建对象时,每个对象共享这个类的行为(类中定义的方法),但会有自己的属性值(不共享状态)。更具体一点:方法代码是共享的,属性数据不共享
Python 中,“一切皆对象”。类也称为”类对象”,类的实例也称为“实例对象”。
定义类的语法格式如下:

Class 类名:
    类体

要点如下:
1.类名必须符合“标识符”的规则;一般规定,首字母大写,多个单词使用“驼峰原则"。
2.类体中我们可以定义属性和方法
3.属性用来描述数据,方法(函数)用来描述这些数据相关的操作,
试验:一个典型的类的定义

class Student:  #类名一般首字母大写,多个单词采用驼峰原则
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def say_score(self): #self必须位于第一个参数
        print('{0}的分数是:{1}'.format(self.name, self.score))
s1=Student('wangs', 18)
s1.say_score()

wangs的分数是:18

构造函数_init_()

类是抽象的,也称之为“对象的模板”。我们需要通过类这个模板,创建类的实例对象,然后才能使用类定义的功能。
一个Python 对象包含三个部分:id(identity 识别码)、type(对象类型)、value(对象的值)。
更进一步的说,一个Python 对象包含如下部分:
1.id(identity 识别码)
2.type(对象类型)
3.value(对象的值):(1) 属性(atribute) (2) 方法(method)
创建对象,我们需要定义构造函数__init__()方法。构造方法用于执行实例对象的初始化工作,对象创建后,初始化当前对象的相关属性,无返回值。

  1. init()的要点如下:
    1.名称固定必须为:init()
    2.第一个参数固定,必须为: self。self 指的就是刚刚创建好的实例对象
    3.构造函数通常用来初始化实例对象的实例属性,如下代码就是初始化实例属性: name和score
def __init__(self,name,score):#构造方法第一个参数必须为 self
        self.name = name   #实例属性
        self.score = score

4.通过“类名(参数列表)”来调用构造函数,调用后,将创建好的对象返回给相应的变量
比如: s1= Student(‘张三’, 60)
5.init()方法:初始化创建好的对象,初始化指的是:“给实例属性赋值”
6.new()方法:用于创建对象,但我们一般无需重定义该方法。
注:
Python中的 self相当于C++中的 self指针,JAVA和 C#中的 this关键字。Python中self必须为构造函数的第一个参数,名字可以任修改,但一般遵守惯例,都叫做:self 。

def __init__(abcd,name,score):#self改成abcd也是可以的,但一般没必要修改
        self.name = name   #实例属性
        self.score = score

实例属性

实例属性是从术语实例对象的属性,也称为“实例变量”。他的使用有如下几个要点:
1.实例属性一般在__init__()方法中通过如下代码定义:

self.实例属性名=初始值

2.在本类的其他实例方法中也是通过 self 进行访问:

self.实例属性名

3.创建实例对象后,通过实例对象访问:

obj01=类名()   #创对象,调用__init__()初始化属性
obj01.实例属性名=#可以给已有属性赋值,也可以新加属性

实验:

class Student:
    def __init__(self,name,score):#构造方法第一个参数必须为 self
        self.name = name   #实例属性
        self.score = score
    def say_score(self): #实例方法
        print('{0}的分数是:{1}'.format(self.name,self.score))
s=Student("小二",60) #通过类名()调用构造函数
s.say_score()
>>> 小二的分数是:60

实例方法

实例方法是从属于实例对象的方法。实例方法的定义格式下:

def 方法名(self ,[形参列表]):
    函数体

方法的调用格式如下:

对象.方法名([实参列表]

在这里插入图片描述
函数和方法的区别:
1.都是用来完成一个功能的语句块,本质一样
2.方法调用时,通过对象来调用,方法从属于特定实例对象,普通函数没有这个特点
3.直观上看,方法定义时需要传递self,函数不需要

其他操作:
1.dir(obj)可以获得对象的所有属性、方法
2.obj.__dict__对象的属性字典
3.pass 空语句
4.isinstance(对象,类型),判断“对象”是不是“指定类型"

class Student:  #类名一般首字母大写,多个单词采用驼峰原则
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def say_score(self): #self必须位于第一个参数
        print('{0}的分数是:{1}'.format(self.name, self.score))
s1=Student('wangs', 18)
s1.say_score()
print(dir(s1))
print(s1.__dict__)

class Man:
    pass

print(isinstance(s1,Man))

wangs的分数是:18
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'say_score', 'score']
{'name': 'wangs', 'score': 18}
False

类对象

当解释器执行class语句时,就会创建一个类对象
试验:测试类对象的生成:

class Student:
    pass #空语句
print(type(Student))
print(id(Student))

Stu2=Student
s1=Stu2()
print(s1)

<class 'type'>
1746135720712
<__main__.Student object at 0x000001968D0A24E0>

类属性和类方法

类属性

类属性是从属于“类对象”的属性,也称为”类变量”。由于,类属性从属于类对象,可以被所有实例对象共享。
类属性的定义方式:

class 类名:
    类变员名=初始值

在类中或者类的外面,可以通过:“类名.类变量名”来读写。

试验:类属性的使用测试:

class Student:
    school='hust'#类属性
    count=0    # 类属性

    def __init__(self,name,score):
        self.name=name #实例属性
        self.score=score
        Student.count=Student.count+1

    def say_score(self):    #实例方法
        print('我的学校是:',Student.school)
        print(self.name,'的分数是:',self.score)

s1=Student('张三',100)  #s1是实例对象,自动调用_init_()方法
s1.say_score()

s2=Student('吴尊',80)
s3=Student('詹姆斯',70)

print('一共创建{0}个Student对象'.format(Student.count))


我的学校是: hust
张三 的分数是: 100
一共创建3个Student对象

在这里插入图片描述

类方法

类方法是从属于“类对象”的方法。类方法通过装饰器@classmethod 来定义,格式如下:

@classmethod
def 类方法名(cls [,形参列表]):
    函数体

要点如下:
1.@classmethod 必须位于方法上面一行
2.第一个cls必须有;cls 指的就是“类对象”本身;
3.调用类方法格式:“类名.类方法名(参数列表)”。参数列表中,不需要也不能给cls传值。
4.类方法中访问实例属性和实例方法会导致错误
5.子类绝承父类方法时,传入 cls是子类对象,而非父类对象

测试:类方法

class Student:
    school='hust'#类属性
    def __init__(self,name,score):
        self.name = name  # 实例属性
        self.score = score
    @classmethod
    def printSchool(cls):
        print(cls.school)
Student.printSchool()

hust

#类方法中访问实例属性和实例方法会导致错误
@classmethod
def printSchool(cls):
    print(cls.school)
    print(self.name) #访问实例属性和实例方法会导致错误
 
print(self.name)
NameError: name 'self' is not defined

静态方法

Python 中允许定义与“类对象”无关的方法,称为“静态方法”。
“静态方法”和在模块中定义普通函数没有区别,只不过“静态方法”放到了“类的名字空间里面”,需要通过“类调用”。
静态方法通过装饰器@staticmethod 来定义,格式如下:

@staticmethod
def 静态方法名([形参列表]):
    函数体

要点如下:
1.@staticmethod必须位于方法上面一行
2.调用静态方法格式:“类名.静态方法名(参数列表)"
3.静态方法中访问实例属性和实例方法会导致错误

class Student:
    school='hust'  #类属性
    @staticmethod
    def add(a,b):  #静态方法
        print("{0}+{1}={2}".format(a,b,a+b))
        return a+b
Student.add(80,55)
80+55=135

del()析构方法和垃圾回收机制

  • del()方法称为“析构方法”,用于实现对象被销毁时所需要的操作。比如:释放对象占用的资源,例如:打开的文件资源、网络连接等。
  • Python实现自动的垃圾回收,当对象没有被引用时 (引用计数为0),由垃圾回收器调用__del__()方法。
  • 我们可以通过del 语句删除对象, 从而保证调用__del__()方法。系统会自动提供__del__()方法,一般不需要自定义析构方法。
class Student:

    def __del__(self):
        print("销毁对象:{0}".format(self))

p1=Student()
p2=Student()
del p2
print("程序结束")
>>>
销毁对象:<__main__.Student object at 0x000001D111DBF7C8>
程序结束
销毁对象:<__main__.Student object at 0x000001D111BBCD48>

这个是python的一个垃圾回收机制 就是说如果你手动del p2这个对象就先执行回收程序。如果不del的话,其他 新建的实例,如p1会在程序最后结束的时候自动调用垃圾回收函数del。这个是默认的机制。

_call_方法和可调用对象

定义了__call__()方法的对象,称为“可调用该对象”,即该对象可以像函数一样被调用。
试验:

class SalaryAccount:
    '''工资计算类'''
    def __call__(self, salary):
        print('算工资啦,,,')
        yearSalary=salary*12
        daySalary=salary//22.5
        hourSalsry=daySalary//8
        return dict(yearSalary=yearSalary,monthSalary=salary,daySalary=daySalary,hourSalsry=hourSalsry)
s=SalaryAccount()
print(s(30000))

算工资啦,,,
{'yearSalary': 360000, 'monthSalary': 30000, 'daySalary': 1333.0, 'hourSalsry': 166.0}
发布了22 篇原创文章 · 获赞 1 · 访问量 459

猜你喜欢

转载自blog.csdn.net/ws297933371/article/details/105610210