第六章 Python面向对象 01-面向对象基础

文章介绍了面向对象编程的基本概念,对比了面向过程和面向对象的思维方式,并通过实例说明了如何在Python中实现面向对象编程。类和对象是核心概念,类是对象的模板,而对象是类的实例。文章还讨论了构造方法用于初始化对象,以及魔术方法在特定时刻自动调用的机制。最后,提到了类与类之间的关系,如继承和相互依赖。
摘要由CSDN通过智能技术生成

面向对象基础

1. 面向对象与面向过程

在我们编写程序的时候,经常性的会听说过“面向对象”这个词语。我们可能听说过Python是“面向对象”的编程语言,C是“面向过程”的编程语言,那么什么是“面向对象”,什么是“面向过程”呢?

  • 面向过程
    • 是一种看待问题、解决问题的思维方式。
    • 着眼点在于问题是如何一步步的解决的,然后亲力亲为的解决问题。
  • 面向对象
    • 是一种看待问题、解决问题的思维方式。
    • 着眼点在于找到一个能够帮助解决问题的实体,然后委托这个实体帮助解决问题。

案例分析1: 小明需要自己组装一台电脑

  • 面向过程的思维方式:
    • (小明)去市场买零配件
    • (小明)将零配件运回家里
    • (小明)将电脑组装起来
  • 面向对象的思维方式:
    • 小明找到一个朋友 – 老王
    • (老王)去市场买零配件
    • (老王)将零配件送回来
    • (老王)将电脑组装起来

案例分析2: 小明需要把大象装进冰箱

  • 面向过程的思维方式:
    • (小明)打开冰箱门
    • (小明)把大象赶进冰箱
    • (小明)关上冰箱门
  • 面向对象的思维方式:
    • (冰箱)开门
    • (大象)自己走进冰箱去
    • (冰箱)关门

因此,无论是面向对象还是面向过程,其实都是一种编程思想,而并不是某一种语言。在很多的新手手中,用“面向对象的语言”写出的代码,仍然是面向过程思想的代码;在很多的大神手中,用“面向过程的语言”也能够写出面向对象思想的代码。那我们应该怎样理解“Python是面向对象的编程语言”这句话呢?

使用Python这门语言可以更加容易写出具有面向对象编程思想的代码!

2. 类与对象

在面向对象的编程思想中,着眼点在于找到一个能够帮助解决问题的实体,然后委托这个实体解决问题。这个具有特定功能,能够帮助解决特定问题的实体,称为一个对象。而由若干个具有相同的特征和行为的对象组成的集合,称为一个类。

类是对象的集合,对象是类的个体

在程序中,我们需要先定义类,在类中定义该类的对象共有的特征和行为。

类是一种自定义的数据类型,通常用来描述生活中的一些场景

例如: Dog类用来描述狗类,

定义了特征: 姓名、性别、毛色

定义了行为: 吃饭、睡觉

那么,这个类的每一个对象都具备这些特征和行为。

3. 类的设计与对象的实例化

我们使用类来描述现实生活中的一些场景,这里我们以狗类为例

# 使用关键字class定义一个类
class Dog:
    def __init__(self):
        # 使用self.定义属性
        self.name = None
        self.age = None
        self.kind = None
        
    # 定义对象的行为,用方法来定义,又称为“成员方法”
    # 成员方法的定义,参数必需添加self,表示对象本身
    def bark(self):
        # 在方法中,使用self.访问对象自己的属性和方法
        print(f"{self.name} 在狗叫")
        
# 实例化对象
xiaobai = Dog()

# 访问类的属性
xiaobai.name = "xiaobai"
xiaobai.age = 1
print(xiaobai.name)
print(xiaobai.age)

# 访问类的方法
xiaobai.bark()

4. 构造方法

我们在一个类中可以定义很多的属性,在使用的时候一个个的进行赋值有点麻烦。因此我们就需要能够在创建对象的同时完成属性的初始化赋值操作,此时就可以使用“构造方法”

# 使用关键字class定义一个类
class Dog:
    # __init__是初始化对象的时候自动调用的方法,称为“构造方法”
    # 在构造方法中,也可以完成属性的定义与初始化赋值操作
    def __init__(self, name, age, kind):
        # 使用self.定义属性,后面直接使用形参完成初始化赋值
        self.name = name
        self.age = age
        self.kind = kind
        
    # 定义对象的行为,用方法来定义
    # 成员方法的定义,参数必需添加self,表示对象本身
    def bark(self):
        # 在方法中,使用self.访问对象自己的属性和方法
        print(f"{self.name} 在狗叫")
        
# 实例化对象
xiaobai = Dog("xiaobai", 1, "samo")

# 访问类的属性
print(xiaobai.name)
print(xiaobai.age)

# 访问类的方法
xiaobai.bark()

5. 魔术方法

在类中存在一些在方法名的前后都添加上__的方法,称为“魔术方法”。魔术方法不需要手动调用,而是在适当的时机自动调用。

魔术方法调用时机使用场景
__new__实例化对象,开辟内存空间的时候调用
__init__初始化对象,属性初始化的时候调用定义属性、完成属性的初始化赋值操作
__del__删除对象的时候调用释放持有的资源等
__cal__对象函数,将对象当作函数调用的时候触发
__str__将对象转成字符串的时候调用str()需要将对象转为自己希望的字符串表示形式
__repr__返回对象的规范字符串表示形式透过容器看对象
__add__使用 + 对两个对象相加的时候调用完成对象相加的逻辑
__sub__使用 - 对两个对象相减的时候调用完成对象相减的逻辑
__mul__使用 * 对两个对象相乘的时候调用完成对象的乘法逻辑
__truediv__使用 / 对两个对象相除的时候调用完成对象的除法逻辑
__floordiv__使用 // 对两个对象相除的时候调用完成对象的向下整除逻辑
__mod__使用 % 对两个对象求模的时候调用完成对象的求模逻辑
__pow__使用 ** 对两个对象求幂的时候调用完成对象的求幂逻辑
__gt__使用 > 对两个对象比较的时候调用完成对象的大于比较
__lt__使用 < 对两个对象比较的时候调用完成对象的小于比较
__ge__使用 >= 对两个对象比较的时候调用完成对象的大于等于比较
__le__使用 <= 对两个对象比较的时候调用完成对象的小于等于比较
__eq__使用 == 对两个对象比较的时候调用完成对象的相等比较
__ne__使用 != 对两个对象比较的时候调用完成对象的不等比较
__contains__使用 in 判断是否包含成员的时候调用完成in判断包含的逻辑
# 定义一个点类
class Point:
    # 完成属性的初始化赋值
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
    # 完成两个点的相加,得到一个新的点
    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)
    
    # 完成两个点的相减,得到一个新的点
    def __sub__(self, other):
        return Point(self.x - other.x, self.y - other.y)
    
    # 判断两个点是否相等,通过属性值是否相等的判断
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
    
    # 判断两个点是否不等,通过属性值是否相等的判断
    def __ne__(self, other):
        return self.x != other.x or self.y != other.y
    
    # 判断一个点的x和y坐标中,是否包含指定的值
    def __contains__(self, elem):
        return elem == self.x or elem == self.y
    
    # 将一个点转为字符串表示形式
    def __str__(self):
        return "{%d, %d}"%(self.x, self.y)
# 定义一个矩形类
class Rect:
    # 完成属性的初始化赋值
    def __init__(self, length, width):
        self.length = length
        self.width = width
    
    # 计算面积
    def getArea(self):
        return self.length * self.width
    
    # 完成两个矩形的面积比较
    def __gt__(self, other):
        return self.getArea() > other.getArea()
    
    def __lt__(self, other):
        return self.getArea() < other.getArea()
    
    def __ge__(self, other):
        return self.getArea() >= other.getArea()
    
    def __le__(self, other):
        return self.getArea() <= other.getArea()
    
    def __eq__(self, other):
        return self.getArea() == self.getArea()
    
    def __ne__(self, other):
        return self.getArea() != self.getArea()
    
    # 将一个矩形转为字符串表示形式
    def __str__(self):
        return f"length: {self.length}, width: {self.width}, area: {self.getArea()}"

关于__str__和__repr__
__str__: 在使用str(obj)的时候触发
__repr__: 官方的描述是返回对象的规范字符串表示形式
两者都是将对象转成字符串的。
如果是直接用print打印的话,会自动的调用str()方法,因此会触发__str__
但是如果需要透过容器看对象的时候,是以__repr__为准的
那么我们应该写__str__还是__repr__呢?
推荐__repr__,因为如果只定义了__repr__,没有定义__str__。此时__str__是与__repr__相同的!


class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        return f"str: name = {self.name}, age = {self.age}"
    
    def __repr__(self):
        return f"repr: name = {self.name}, age = {self.age}"
    
    
xiaobai = Person("xiaobai", 18)

# 直接打印
print(xiaobai)		# str: name = xiaobai, age = 18

# 放入容器
arr = [xiaobai]
print(arr)			# repr: name = xiaobai, age = 18

6. 类与类的关系

我们在一个程序中,可能会设计很多的类,而类与类之间的关系可以分为3种:

  • 类中使用到另外一个类的对象来完成对应的需求
  • 类中使用到另外一个类的对象作为属性
  • 继承
使用到另一个类的对象完成需求
"""
案例: 上课了,老师让学生做自我介绍
分析:
    1、需要设计两个类: 老师类 和 学生类
    2、老师类的功能: 让学生做自我介绍
    3、学生类的功能: 自我介绍
"""


class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduce(self):
        print(f"大家好,我叫{self.name},我今年{self.age}岁了!")


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

    def make_introduce(self, student):
        print(f"{self.name}说: 各位同学安静一下,我们听{student.name}来做自我介绍")
        print(f"{student.name}: ", end="")
        student.introduce()


# 实例化老师和学生的对象
xiaoming = Student("xiaoming", 19)
laowang = Teacher("laowang")

laowang.make_introduce(xiaoming)
使用到另一个类的对象作为属性
"""
案例: 判断一个圆是否包含一个点
分析:
    需要设计的类: 圆类、点类
    
    点类需要设计的属性: x, y坐标
    圆类需要设计的属性: 圆心(点类型), 半径
"""


# 定义点类
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return "{%d, %d}"%(self.x, self.y)


# 定义圆类
class Circle:
    def __init__(self, center, radius):
        self.center = center
        self.radius = radius

    # 判断是否包含一个点
    def contains_point(self, point):
        distance = (self.center.x - point.x) ** 2 + (self.center.y - point.y) ** 2
        return distance <= self.radius ** 2

    def __contains__(self, item):
        return self.containsPoint(item)


# 创建点对象
point = Point(10, 20)
# 创建圆对象
circle = Circle(Point(5, 18), 8)
# 判断圆是否包含点
print(circle.contains_point(point))
print(point in circle)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值