python面向对象编程基础

面向对象编程(Object-oriented Programming,OOP) 是一种编程范式(编程思想)

一、类和对象

概念

对象:现实世界中每一个事物都是一个对象,是一个具体的概念。

类:拥有相同的属相和功能的事物成为一个类,是一个抽象的概念。

拥有相同属性和功能的具体事物则成为这个类的实例对象。

例如:

狗的属性是有尾巴,有毛,四条腿等,功能是能汪汪叫,能吃骨头,能咬人等。能有这些
属性和功能的事物我们就认为属于狗。而金毛是这个类的具体实例对象
电脑的属性是有CPU,存储器,操作系统等,功能就是能安装APP,能连网等。能有这些属性
和功能的事物我们就认为属于电脑类。而联想电脑是这个类的具体实例对象
汽车的属性是有四个轮子,一个地盘,一个方向盘等,功能是能行驶,能加速,能刹车
等。能有这些属性和功能的事物我们就认为属于汽车类。而小米汽车是这个类的具体实例对象

具体代码举例:

# 狗类
class Dog:
    # 类的属性
    legs_num=4
    has_hair=True
    has_tail=True
    # 实例方法(第一个参数是self实例对象而不是cls类对象,故为实例方法)
    def bark(self):
        print("狗会汪汪叫")
    def bite(self):
        print("狗会咬坏人")
    def fetch(self):
        print("狗会捡球")

#鸟类
class Bird:
    # 类的属性
    legs_num = 2
    has_hair = True
    has_tail = False

    # 实例方法
    def fly(self):
        print("鸟会飞")

    def eat_worms(self):
        print("鸟吃虫子")

    def nest(self):
        print("鸟会筑巢")

狗类实例化:

# 狗类的实例化
Jinmao=Dog()
# 调用类的属性和功能
print(Jinmao.legs_num)
Jinmao.bite()

运行结果:

 

鸟类实例化:

# 鸟类的实例化
Maque=Bird()
# 调用类的属性和功能
print(Maque.legs_num)
Maque.nest()

运行结果:


语法

类名:推荐首字母大写,多个单词则采用大驼峰命名法(ExampleName),不能以数字开头

同一个类的不同具体实例对象,存储位置不同,在不同的实例空间;同一个类的不同具体实例对象调用共同的属性和方法,存储位置相同,都在类空间。


二、实例对象

实例对象的实例属性

类属性在所有实例化对象中作为公用资源存在的,实例属性是属于类的每个实例对象的特定属性,实例属性是在创建对象时赋予的,每个对象可以具有不同的实例属性值。

Jinmao=Dog()
Bixiong=Dog()

# 实例属性
Jinmao.name='金毛'
Bixiong.name='比熊'

 

注意:会报错,因为查找顺序按照[实例空间,类空间],Jinmao.bark()会被认为是1000(),int类型的值并不能作方法名,也没有该方法

Jinmao.bark=1000 # 存储在实例空间
Jinmao.bark() # 存储在类空间

如果通过实例对象.属性=属性值,该属性与属性值会存放在实例空间内,即使该属性是类属性,调用时,优先返回实例空间的值


实例对象的实例方法

 何时使用哪种方法?

  • 若方法需要读写实例属性(如self.name),第一个形参是self实例对象,用实例方法

  • 若方法需要修改类属性(如全局配置)或提供多种构造方式(工厂),第一个形参是cls类对象用类方法

  • 如果方法既不需要实例也不需要类属性,考虑使用静态方法@staticmethod)。

# 狗类
class Dog:
    # 类的属性
    legs_num=4
    has_hair=True
    has_tail=True

    # 实例方法
    def bark(self):
        print(f"{self.name}会汪汪叫") # 调用了实例属性

    def bite(self,person):
        print(f"狗会咬{person}")

Jinmao=Dog()

# 实例属性
Jinmao.name='金毛'

Jinmao.bite("坏人") # 传参时没有传self,self默认为当前所调用实例方法的实例对象(即Jinmao)
Jinmao.bark()

 输出结果:


 

三、构造方法 

上述代码,对象的属性是通过直接赋值给对象的实例属性来实现的,但是一般是使用构造方法来初始化对象的属性。减少代码冗余,提高可维护性

# 狗类
class Dog:
    def __init__(self,name,breed,color,age):
            self.name=name
            self.breed=breed
            self.color=color
            self.age=age
    def show_infos(self):
        print(f"名字:{self.name},品种:{self.breed},颜色:{self.color},年龄:{self.age}")

Jinmao=Dog("小鸡毛","金毛","黄色","两岁")
Jinmao.show_infos()

运行结果:

 


 

四、类对象

类对象和类属性

# 这里的Car就是一个类变量
class Car (object):
    total_cars=0
    def __init__(self,make,model):
        self.make=make
        self.model=model
        Car.total_cars+=1 # 类对象.类属性,只有这样才能改变类属性的值

    # 实例方法
    def accelerate(self):
        print(f"一辆{self.make}的{self.model}正在加速")

car1=Car("Toyota","Camry")
car2=Car("Honda","Accord")
print(Car.total_cars)

那类对象可不可以调用实例方法呢?运行以下代码:

Car.accelerate()

运行结果,如下:

缺少参数,修改代代码,如下: 

car1=Car("Toyota","Camry")
Car.accelerate(car1)

运行结果,如下:

故类对象不能像实例对象一样,不能通过self传递,必须手动添加参数,但通常不会使用类对象调用实例方法 


类方法

用于读写类属性,使用装饰器@classmethod

# 类方法
    @classmethod
    def show_total_cars(cls):
        print(f"当前的total_cars:{Car.total_cars}")

# 调用类方法
Car.show_total_cars()

也可以改写成以下形式,在类方法中用cls代替Car类对象,代码可维护性变高
同理,在实例方法中用self代替实例对象

# 类方法
    @classmethod
    def show_total_cars(cls):
        print(f"当前的total_cars:{cls.total_cars}")

# 调用类方法
Car.show_total_cars()

构造方法中的类对象可以使用,self.__class__代替

    def __init__(self,make,model):
        self.make=make
        self.model=model
        self.__class__.total_cars+=1 # 类对象.类属性,只有这样才能改变类属性的值

完整代码如下:

# 这里的Car就是一个类变量
class Car (object):
    total_cars=0
    def __init__(self,make,model):
        self.make=make
        self.model=model
        self.__class__.total_cars+=1 # 类对象.类属性,只有这样才能改变类属性的值

    # 实例方法
    def accelerate(self):
        print(f"一辆{self.make}的{self.model}正在加速")

    # 类方法
    @classmethod
    def show_total_cars(cls):
        print(f"当前的total_cars:{cls.total_cars}")

car1=Car("Toyota","Camry")
car2=Car("Honda","Accord")
print(Car.total_cars)
Car.accelerate(car1)

五、静态方法 

 定义:使用装饰器@staticemethod。参数随意,没有self和cls参数,方法体中不能使用类或实例的任何属性和方法

调用:类对象或实例对象都可以调用

class Cal():
    @staticmethod
    def add(x,y):
        return x+y

    @staticmethod
    def mul(x,y):
        return x*y
cal=Cal()
print(cal.add(3,5))
# or
print(Cal.add(3,5))

运行结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值