python面向对象(part1)--类和对象

学习笔记
开发工具:Spyder



概述

① 面向过程:分析解决问题的步骤,然后逐步实现.
② 面向对象:找出解决问题的人,然后分配职责.
③类:创建对象的模板,是抽象的概念.
④对象: 是具体的,存储的是数据.
从设计角度讲:先有对象,再创建类.
从编码角度讲:先有类,再创建对象.
⑤类与类区别:行为不同.
对象与对象区别:数据不同.

面向过程

面向过程是分析出解决问题的步骤,然后逐步实现。

  • 公式

程序 = 算法 + 数据结构

  • 优缺点

优点:所有环节、细节自己掌控。
缺点:考虑所有细节,工作量大。

面向对象

面向对象是找出解决问题的人,然后分配职责。

  • 公式

程序 = 对象 + 交互

  • 优点

①思想层面:
更接近于人的思维方式。
有利于梳理归纳、分析解决问题。
②技术层面:
高复用:对重复的代码进行封装,提高开发效率。
高扩展:增加新的功能,不修改以前的代码。
高维护:代码可读性好,逻辑清晰,结构规整。

类和对象

一个抽象的概念,即生活中的”类别”。

  • 对象

类的具体实例,即归属于某个类别的”个体”。

  • 类是创建对象的”模板”。

数据成员:名词类型的状态。
方法成员:动词类型的行为。

举个例子

代码:

①创建类

②创建对象

结果:

由上述结果可知,创建不同对象的地址会不同。变量w01为大白对象的地址,变量w02为小黄对象的地址.通过对象地址,调用对象方法,会自动传递对象地址。

内存图:

①当程序自上而下运行,运行到我们创建的类时,程序会在内存的方法区内,存放类的代码和方法的代码。

②当程序运行到创建对象的代码时【w01 = Bunny("大白", 5, "公")】,程序就会执行__init__()方法。程序会在方法区中找到我们需要执行的语句,然后在内存中再开辟一块空间(栈帧)。在创建对象,并传入参数时,我们不仅仅传入了3个参数【“大白”, 5, “公”】,实际上会(自动的)多传一个参数(创建的对象的地址)。最后,将Bunny对象赋值给了变量w01。

③当创建完对象后,__init__()方法结束了它的使命,__init__栈帧就弾栈了。

④当程序运行到调用对象方法时【w01.eating()】,程序会在内存中再开辟一块空间(栈帧)。这个eating()方法中只有self一个变量,这个self变量存储的就是我们之前创建的Bunny对象的内存空间

⑤最后,eating()方法结束使命,eating栈帧弾栈。

语法

定义类

  • 代码
class 类名:
    
	"""文档说明"""
	def _init_(self,参数列表):
		self.实例变量 = 参数
  方法成员
  
  • 说明

①类名所有单词首字母大写。
_init_ 也叫构造函数,创建对象时被调用。
③ self 变量绑定的是被创建的对象。

创建对象(实例化)

变量 = 构造函数(参数列表)

实例成员

实例变量(对象的变量)

  • 语法

定义实例变量:

对象.变量名

调用实例变量:

对象.变量名
  • 说明

①通过对象.变量名,对实例变量赋值

class Bunny:
    pass


#创建对象(实例化)
w01 = Bunny()
#通过`对象.变量名`,对实例变量赋值
w01.name = "小黄"
print(w01.name) #小黄

②通常在构造函数(__init__)中,对实例变量赋值

class Bunny:
    def __init__(self, name):
        self.name = name
    

#通常在构造函数中,对实例变量赋值
w01 = Bunny("小黄") 
print(w01.name) #小黄

③通过成员方法,对实例变量赋值

class Bunny:
    def __init__(self, name):
        self.name = name
    
    def fun01(self):
        self.age = 10

#通常在构造函数中,对实例变量赋值
w01 = Bunny("小黄")
w01.fun01()
print(w01.name) #小黄
print(w01.age) #10
  • 对象的属性__dict__
class Bunny:
    def __init__(self, name, age):
        self.name = name
        self.age = age


w01 = Bunny("小黄", 6)
print(w01.__dict__) #{'name': '小黄', 'age': 6}

实例方法(对象的方法)

  • 语法

定义实例方法:

def 方法名称(self, 参数列表):
    方法体

调用实例方法:

对象地址.实例方法名(参数列表)
  • 说明

①至少有一个形参,第一个参数绑定调用这个方法的对象,一般命名为"self"
②无论创建多少对象,方法只有一个,并且被所有对象共享。

类成员

类变量

类变量在类中,方法外。类变量可以被所有创建的对象所共享。

  • 语法

类变量定义:

class 类名:
    变量名 = 表达式

类变量调用:

类名.变量名
  • 例子1

代码:

class Bunny:
    
    leg = 4
    
    def __init__(self, name, age):
        self.name = name
        self.age = age


b01 = Bunny("小黄", 6)
print("%s有%d条腿" % (b01.name, Bunny.leg))

结果:

  • 例子2

代码:

class Store:
    
    capacity = 1000
    
    def __init__(self, name, extract):
        self.name = name
        self.extract = extract
        
        Store.capacity -= extract


print("剩余存储量", Store.capacity)
s01 = Store("A", 20)
print("剩余存储量", Store.capacity)
s02 = Store("B", 30)
print("剩余存储量", Store.capacity)

结果:

内存图:

①【s01 = Store(“A”, 20)】

②【s02 = Store(“B”, 30)】

类方法

类方法用于操作类变量。

  • 语法

定义类方法:

@classmethod
def 方法名称(cls, 参数列表):
    方法体

调用类方法:

类名.方法名(参数列表)
  • 说明

①类方法至少有一个形参,第一个形参用于绑定类,一般命名为’cls’
②使用@classmethod修饰的目的,是调用类方法时可以隐式传递类。
③类方法中不能访问实例成员(实例变量、实例方法),实例方法中可以访问类成员。

  • 例子

代码:

class Bunny:
    
    leg = 4
    
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    @classmethod
    def count_leg(cls):
        print("兔兔腿数:", cls.leg)


Bunny.count_leg()

结果:

静态方法

静态方法既不能用访问成员,也不能访问类成员。

  • 啥是静态方法?什么时候用静态方法?

如果有一个方法,不把它放在类中,单独存在也可以解决我们的问题。但是,为了满足面向对象的开发思想,我们必须把它放在类中,这时,这个方法就是静态方法。

  • 语法

定义静态方法:

@staticmethod
def 方法名称(参数列表):
    方法体

调用静态方法:

类名.方法名(参数列表)
  • 例子

代码:

class Bunny:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    @staticmethod
    def my_method():
        print("保护环境")


Bunny.my_method()

结果:

发布了116 篇原创文章 · 获赞 22 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/m0_37422217/article/details/105109611