https://developer.aliyun.com/article/1495767

简介: https://developer.aliyun.com/article/1495767

oop 面向对象的程序开发

面向对象程序设计(Object Oriented Programming)作为一种新方法,其本质是以建立模型体现出来的抽象思维过程和面向对象的方法

一、面向过程和面向对象

1.面向过程

是一种以事件为中心的编程思想,更关注过程。简单的问题可以用面向过程的思路来解决,直接有效,

但是当问题的规模变得更大时,用面向过程的思想是远远不够的。所以慢慢就出现了面向对象的编程思想。

优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发,性能是最重要的因素。

缺点:不易维护、复用和拓展

2.面向对象

世界上的每个人或事务都能看成一个对象,每个对象都有自己的属性和行为,对象与对象之间通过方法来交互。

面向对象是一种以“对象”为中心的编程思想,把要解决的问题分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个对象在整个解决问题的步骤中的属性和行为。

优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护

缺点:性能比面向过程低

3.扩展:高内聚、低耦合

①内聚:模块内部的代码,例如方法,变量,对象,或者是功能模块。相互之间的联系越强,内聚就越高,模块的独立性就越好。一个模块应该尽量的独立,去完成独立的功能

②耦合:模块与模块之间有些操作是有关联的,例如水桶效应,一个水桶若是有一块木板比其他木板短,那么这个水桶装的水也就会相应减少,因此模块与模块之间的关系越是紧密,独立性就越不好,就容易产生连锁反应

③模块:就是将大型系统的复杂问题,分成不同的小模块,去处理问题

二、Python面向对象

类(Class)与对象(Object)

类(Class)是用来描述具有相同属性(Attribute)和方法(Method)对象的集合。

对象(Object)是类(Class)的具体实例。比如学生都有名字和分数,他们有着共同的属性。

这时我们就可以设计一个学生类, 用于记录学生的名字和分数,并自定义方法打印出他们的名字和分数。

属性(Attribute): 类里面用于描述所有对象共同特征的变量或数据。比如学生的名字和分数。

方法(Method): 类里面的函数,用来区别类外面的函数, 用来实现某些功能。比如打印出学生的名字和分数。

理解面向对象

面向对象是一种抽象化的编程思维,很多编程语言都有的一种思想

面向对象就是将编程当做一种事物,对外界来说,事物是直接使用的,不用管他内部的情况。

而编程就是设置事物能做什么事

面向对象两个重要组成部分:类和对象

类和对象的关系:用类创建对象,也可以说成用类实例化对象

类是对一系列具有相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物。

特征即属性

行为即方法

对象是类的具体实例

#*类中的成员只有方法和属性,不要裸露的把判断和循环直接写在类中,而是用方法包起来

代码追求高内聚,低耦合

(1) 类的定义

#1 经典类

class Car:

pass

#2 新式类 推荐

class Car():

pass

#3.如果一个类不去写继承哪个类,默认继承的是object, object类是顶级类或基类。其他子类叫派生类

class Car(object):

pass

(2)类的实例化,就是创建对象

创建对象:

对象名 = 类名()

对象调用方法

对象.方法名()

class Car():
    pass
    
obj = Car()
print(obj)

(3)类的基本结构

类中两样东西:

(1)成员属性 即是变量

(2)成员方法 即是函数

class Car():

# 成员属性

color = “白色”

# 成员方法

def didi():

print(“小车会嚓嚓的叫”)

方法分类

普通方法: 没有任何参数传递,只能类调用

绑定方法: 把默认传参的方法叫做绑定方法,绑定到对象(默认传对象),绑定到类(默认传类)

非绑定方法:静态方法(无需传任何参数,对象和类都能调用)

定义成员方法必须带有第一个参数,通常叫做 self。也可以自定义。这种方法叫做绑定方法,把对象传给成员方法

如果不带参数,对象调用成员方法会报错,说必须一个参数。一般可以用self填充

pycharm提示

在类中定义方法时,若该方法不涉及对成员属性的操作,那么Pycharm会提示Method xxx may be ‘static’,因为Pycharm会认为该方法是一个静态方法,而不是类方法,

所提提示我们在该方法前添加@staticmethod装饰器进行装饰。

或者在方法中对成员属性有调用

#下面情况,语法上不报错,但是严禁使用,破坏了类中的结构,不要裸露的把判断和循环直接写在类中,而是用方法包起来

class Car():
    if 5 ==5 :
        print(11223344)

类中的代码可以直接运行。这与其他语言不同,体现了python语言的灵活性。但这样写不规范,应将判断或循环放在成员方法中

(4)类的命名

类的命名 : 推荐使用大驼峰命名法,每个单词的首字母都要大写"“”

mycar => MyCar

zhangbaozhang => ZhangBaoZhang

三、面向对象的封装 - 对象的操作

面向对象三大特征: 封装 继承 多态

#-封装:对类中成员属性和方法的保护,控制外界对内部成员的访问,修改,删除等操作

#-继承:一个类除了自身所拥有的属性方法之外,还获取了另外一个类的成员属性和方法

#-多态:不同的子类对象,调用相同的父类方法,产生不同的执行结果

python对成员的保护分为两个等级

私有的: private

在本类内部可以访问,类的外部不可以访问.(python中 属性或者方法前面加上两个下划线__)

公有的: public

在本类的内部和外部都可以访问.

#(了解)在其他高级语言当中,如java php c++等语言,有三个等级 private public protected

封装:

1.私有 : 在类内可以互相访问,在类外不能访问

2.公有 : 在类内或者类外都可以访问

类中成员:

1.成员属性

2.成员方法

绑定方法:

1.绑定到对象 : 当对象去调用类中成员方法时, 系统会默认把该对象当成参数传递给该方法

2.绑定到类 : 当对象或者类去调用类中成员方法时,系统会默认把该类当成参数传递给该方法

使用方式:

对象.成员属性

对象.成员方法

绑定对象方法必须带一个参数,把类或对象传递给该方法。不然报错

成员方法加个self参数,当然也可以定义成其他名字,但一般默认用self,代表本对象。当对象调用该方法时,系统将该对象通过改参数传递给 该方法

self就是创建的对象car

(1)实例化的对象访问成员属性和方法

class MyCar():
    # 公有属性
    logo = "布加迪威龙"
    
    # 私有属性
    __price = "2000万"
    
    # 公有方法
    def run(self):
        print("百公里油耗300L,logo={} , price={}".format(self.logo, self.__price))

    # 私有方法
    def __info(self):
        print("车主信息保密,据说是某个房地产大佬的儿子")

# 实例化对象(类的实例化)
obj = MyCar()


# 公有
print(obj.logo)
obj.run()

# 私有 (私有成员无法在类外访问,类内可以)
# obj.__price error
# obj.run()
# obj.__info() error


私有属性在外面不能被访问,但可以通过类的共有方法,在类内调用访问私有属性,类外调用共有方法来实现对私有属性的访问

调用私有方法,在共有方法里面调用私有方法,然后对象调用这个共有方法。

(2)实例化的对象动态添加公有成员属性

obj.color = "香槟橙"
obj.logo = "玛莎拉蒂" 
print(obj.color)
print(obj.logo)

#__dict__ 获取类,对象的内部成员
对象可以使用类的成员,但不能说类的成员是对象的成员。一个类可以实例化出很多对象

4b9ccecd53c44cf9acba7490a98fe914.png

print(obj.__dict__)   #通过对象添加,修改的成员才是对象的内部成员,跟类内部到成员没关系。一个类可以实例化出很多对象
print(MyCar.__dict__)

(3)实例化的对象动态添加公有成员方法

1.无参方法
def dahuangfeng():
    print("请加我大黄蜂")

obj.dahuangfeng = dahuangfeng  ##将dahuangfeng这个函数赋值给dahuangfeng这个obj对象的内部成员
obj.dahuangfeng()

对象调用类外面的方法不会自动传参,类里面的才会自动传参

2.有参方法

#基本版

def qingtianzhu(name):
    print("请叫我一柱擎天么,{}".format(name))
    
obj.qingtianzhu = qingtianzhu
obj.qingtianzhu("擎天柱")

#升级版。自己传递对象参数

def qingtianzhu(obj,name):
    print("请叫我一柱擎天么,{},我的颜色是{}".format(name,obj.color))

obj.qingtianzhu = qingtianzhu
obj.qingtianzhu(obj,"擎天柱")

3.究极版

“”“如果要创建绑定方法,参数的顺序,self对象本身要放到第一位.”“”

def qingtianzhu(obj,name):
    print("请叫我一柱擎天么,{},我的颜色是{}".format(name,obj.color))

import types
#创建绑定方法,系统自动把该对象当成参数传递给方法;
#types.MethodType(方法,对象) => 绑定方法   
res = types.MethodType(qingtianzhu,obj)
print(res)

#把绑定方法赋值给对象成员qingtianzhu


obj.qingtianzhu = types.MethodType(qingtianzhu,obj)
obj.qingtianzhu("擎天柱")

#3.lambda表达式

obj.weizhentian = lambda : print("我是威震天")
obj.weizhentian()

四、面向对象的封装 - 类的操作

使用方式:

类.成员属性

类.成员方法

class MyCar():
    
    # 公有成员属性
    platenum = "京A7758BB"
    
    # 私有成员属性
    __earning = "月收入6000"
    
    # 公有成员方法
    def car_info():
        print("牌照信息可以公开")
        print("<======>")
        MyCar.__money_info()
    
    # 私有成员方法
    def __money_info():
        print( "收入信息保密" , MyCar.__earning )

(1)定义的类访问公有成员属性和方法

print(MyCar.platenum)
MyCar.car_info()

#MyCar.__money_info() error


类可以访问不带参数的类成员方法

(2)定义的类动态添加公有成员属性

MyCar.oil = "1000L"
print(MyCar.oil)
print(MyCar.__dict__)

(3)定义的类动态添加公有成员方法

在类外创建双下划线开头的方法也只是普通方法。只有在类内的双下划线开头的方法才是私有方法

一般在类外添加

#1.无参方法

def car_light():
    print("我是造车灯的方法")
MyCar.car_light = car_light
MyCar.car_light()

#2.有参方法

def car_engine(name):
    print("我是造{}发动机的方法".format(name))
MyCar.car_engine = car_engine
MyCar.car_engine("三缸发动机")

#3.lambda表达式

MyCar.luntai = lambda : print("我是造轮胎的方法")
MyCar.luntai()

类内访问私有方法

#类内通过类访问私有方法,可以借助类内共有的方法,间接访问类内私有方法

五、对比 对象和类之间的不同

1.类中的无参方法默认只能类来调用,对象无法调取

2.对象可以调用类中的成员,反过来,类不能调用对象中的成员

3.每创建一个对象都会在内存中占用一份空间,对象之间是彼此独立的;

obj = MyCar()
#obj.car_info() error
MyCar.car_info()


obj.price = "10万"
print(MyCar.price)

相关文章
|
8月前
https://blog.csdn.net/njpkhuan/article/details/100563673?spm=1001.2014.3001.5502
https://blog.csdn.net/njpkhuan/article/details/100563673?spm=1001.2014.3001.5502
|
2月前
|
C++
【C/C++ 编程 入门篇】 if条件判断表达式的使用教程
https://developer.aliyun.com/article/1465430
20 0
|
2月前
|
JSON 前端开发 数据格式
https://tigerhhzz.blog.csdn.net/article/details/129961946?spm=1001.2014.3001.5502
https://tigerhhzz.blog.csdn.net/article/details/129961946?spm=1001.2014.3001.5502
11 0
|
4月前
https://developer.aliyun.com/article/1417518
https://developer.aliyun.com/article/1417518
30 0
|
4月前
|
XML Java 数据格式
javaweb实训第五天下午——xml配置文件约束报错问题
问题描述: 如果电脑连不上网,或者网速不好可能会造成Spring框架中xml配置文件出现错误。但是这个错误不影响项目的运行的;
22 0
|
5月前
|
存储 缓存 算法
计算机原理组成篇 (2)
主存-辅存层次 原理:局部性原理 实现:主存之外增加辅助存储器(磁盘、SD卡、U盘等) 目的:解决主存容量不足的问题
97 0
|
9月前
|
Serverless
7-9 拯救外星人
你的外星人朋友不认得地球上的加减乘除符号,但是会算阶乘 —— 正整数 N 的阶乘记为 “N!”,是从 1 到 N 的连乘积。所以当他不知道“5+7”等于多少时,如果你告诉他等于“12!”,他就写出了“479001600”这个答案。
139 0
|
12月前
|
Java API Spring
https://developer.aliyun.com/article/1224754
https://developer.aliyun.com/article/1224754
73 0
|
JavaScript
https://developer.aliyun.com/article/1192111
我写了两个函数一个是数字类型的函数,另一个是字符串类型的函数,其实就是类型不同,实现的功能是一样的,这时候我们就可以使用泛型来优化
524 0
https://developer.aliyun.com/article/1192111