【100天精通python】Day12:面向对象编程_属性和继承的基本语法与示例

news2024/11/24 9:35:29

      目录

1 属性(Attributes)

1.1 属性的基本语法

1.2 创建用于计算的属性

1.3 属性的安全保护机制

2 继承(Inheritance)

2.1 继承的基本语法

2.2 方法的重写

2.3 派生类中调用基类的_init_()方法

3 总结 


         属性是类的特征或数据成员,可以包含各种数据类型,如整数、字符串、列表等。通过属性,我们可以为类定义各种特征和行为。

        继承是一种类之间的关系,它允许一个类(称为子类)继承另一个类(称为父类)的属性和方法。通过继承,子类可以重用父类的功能,并且还可以根据需要添加新的属性和方法。

  • 属性表示对象的状态或数据,是对象的特征。在面向对象编程中,类可以定义属性,而实例则拥有这些属性的具体值。
  • 继承是一种对象间的关系,一个类可以继承另一个类的属性和方法,从而复用已有的代码并扩展功能。
  • 继承允许我们建立类的层次结构,从抽象类继承出具体的子类,子类可以拥有父类的所有属性和方法,同时也可以根据需要添加自己特有的属性和方法。

1 属性(Attributes)

在Python中,可以通过在类中定义变量来创建属性。这些变量被称为实例变量或属性。每个实例变量都属于类的一个实例,并且可以根据需要分配不同的值。

1.1 属性的基本语法

定义属性:属性通常在类的内部定义,可以通过在类中声明变量来创建属性。属性可以是实例属性(属于类的实例)或类属性(属于类本身)。

class MyClass:
    # 定义实例属性
    instance_var = 10
    
    def __init__(self):
        # 初始化实例属性
        self.name = "John"

访问属性:在类的方法中可以通过使用self关键字来访问实例属性。对于类属性,可以使用类名来访问。

class MyClass:
    class_var = 20
    
    def __init__(self):
        self.instance_var = 10
        
    def get_class_var(self):
        # 访问类属性
        return MyClass.class_var
    
    def get_instance_var(self):
        # 访问实例属性
        return self.instance_var

修改属性:类的方法可以通过self关键字修改实例属性的值。

class MyClass:
    def __init__(self):
        self.instance_var = 10
        
    def set_instance_var(self, value):
        # 修改实例属性的值
        self.instance_var = value

属性的可见性:在Python中,默认情况下,类的所有属性都是公有的,可以在类的外部访问。如果希望将属性设置为私有的,可以在属性名前添加两个下划线__

class MyClass:
    def __init__(self):
        # 私有属性
        self.__private_var = 10
        
    def get_private_var(self):
        # 访问私有属性
        return self.__private_var
    
    def set_private_var(self, value):
        # 修改私有属性的值
        self.__private_var = value

属性的装饰器:可以使用@property装饰器将类的方法转换为属性。这样可以在使用属性时像访问属性一样调用方法。

class MyClass:
    def __init__(self):
        self.__private_var = 10
        
    @property
    def private_var(self):
        # 使用装饰器将方法转换为属性
        return self.__private_var

示例:

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

car1 = Car("Toyota", "Corolla", 2022)
car2 = Car("Honda", "Civic", 2021)

print(car1.make)  # 输出:Toyota
print(car2.year)  # 输出:2021

在上面的示例中,我们创建了一个名为Car的类,并在初始化方法__init__中定义了三个属性:make、model和year。然后,我们创建了两个Car类的实例,并为每个实例分配了不同的值。

1.2 创建用于计算的属性

        在Python中,我们可以使用@property装饰器来创建用于计算的属性。计算属性是一种通过调用特定方法计算得到的属性值,而不是直接存储在实例变量中的值。计算属性可以根据其他实例变量的值来计算,或者进行复杂的计算逻辑。

        使用@property装饰器可以创建用于计算属性的语法格式。@property装饰器允许我们将一个方法转换为只读属性,该属性的值是通过计算而来,而不是存储在实例变量中。

        以下是@property的语法格式:

class ClassName:
    def __init__(self, ...):
        # 初始化实例变量

    @property
    def attribute_name(self):
        # 计算属性的逻辑
        return computed_value

在上面的语法格式中:

  • ClassName 是类的名称,表示我们正在定义一个类。
  • ...__init__方法的参数列表,用于初始化实例变量。
  • attribute_name 是计算属性的名称,可以根据实际情况来指定。
  • computed_value 是通过计算得到的属性值,可以根据实际情况来计算。

使用@property装饰器可以将一个方法定义为计算属性,并且可以像访问普通属性一样访问它。当访问计算属性时,实际上是调用了被@property装饰的方法,并返回该方法的返回值作为属性值。

在使用@property装饰器时,需要注意以下几点:

  1. 计算属性的名称和实例变量的名称应该不同,否则会导致无限递归。
  2. 计算属性只能用于读取,不能用于修改。如果想要修改计算属性的值,需要定义一个对应的setter方法,并使用@property.setter装饰器。

下面是一个示例,演示如何创建一个计算属性:

class Circle:
    def __init__(self, radius):
        self.radius = radius

    @property
    def diameter(self):
        return self.radius * 2

    @property
    def area(self):
        return 3.14 * (self.radius ** 2)

    @property
    def circumference(self):
        return 2 * 3.14 * self.radius

# 创建Circle对象
circle = Circle(5)

# 访问计算属性
print(circle.diameter)  # 输出:10
print(circle.area)  # 输出:78.5
print(circle.circumference)  # 输出:31.400000000000002

# 修改radius属性并重新计算计算属性
circle.radius = 8
print(circle.diameter)  # 输出:16
print(circle.area)  # 输出:201.12
print(circle.circumference)  # 输出:50.24

        在上面的示例中,我们创建了一个名为Circle的类,其中包含radius属性和三个计算属性:diameter、area和circumference。通过@property装饰器,我们将这三个方法定义为计算属性,并通过访问这些计算属性来获取计算得到的结果。

        计算属性可以动态地计算属性值,而不需要额外的存储空间,从而节省了内存和代码维护成本。在实际应用中,计算属性常用于根据对象的其他属性来计算相关的值,或者进行复杂的数学计算和逻辑操作。

1.3 属性的安全保护机制

在Python中,可以通过设置访问控制来为属性设置安全机制,以防止意外地修改或访问属性。在Python中,有两种常用的访问控制方式:公开访问和私有访问。

公开访问: 公开访问是Python默认的属性访问方式,即所有属性都可以直接访问和修改。这种方式没有访问控制,属性的访问和修改是完全开放的。例如:

class Circle:
    def __init__(self, radius):
        self.radius = radius

circle = Circle(5)
print(circle.radius)  # 输出:5
circle.radius = 8
print(circle.radius)  # 输出:8

私有访问: 为了设置安全机制,可以在属性名前加上两个下划线"__",将属性设置为私有属性。私有属性只能在类的内部访问,外部无法直接访问和修改。要访问私有属性,可以通过公开的访问接口进行间接访问。例如:

class Circle:
    def __init__(self, radius):
        self.__radius = radius

    def get_radius(self):
        return self.__radius

    def set_radius(self, radius):
        if radius > 0:
            self.__radius = radius

circle = Circle(5)
print(circle.get_radius())  # 输出:5
# 试图直接访问私有属性将报错
# print(circle.__radius)  # 报错:'Circle' object has no attribute '__radius'

circle.set_radius(8)
print(circle.get_radius())  # 输出:8

通过以上示例,我们在属性名前添加了两个下划线"__",将radius属性设置为私有属性。为了访问和修改私有属性,我们定义了公开的访问接口get_radius()和set_radius(),通过这些接口间接地访问和修改私有属性。

通过使用私有属性和公开访问接口,可以在类的内部控制对属性的访问和修改,从而实现属性的安全性。这样可以防止外部不恰当地修改属性,保护了属性的完整性和数据安全。

2 继承(Inheritance)

        继承是面向对象编程中的一个重要概念,它允许我们创建一个新的类(称为子类)来继承另一个已有类(称为父类)的属性和方法。子类可以继承父类的所有公有成员,并且还可以添加自己的成员。继承使得代码重用和组织变得更加简单和有效。

2.1 继承的基本语法

class ParentClass:
    # 父类的属性和方法

class ChildClass(ParentClass):
    # 子类继承父类的属性和方法,并可以添加自己的属性和方法

在上面的语法中,我们首先定义了一个父类ParentClass,其中包含一些属性和方法。然后我们定义一个子类ChildClass,并在括号中指定父类名ParentClass。子类ChildClass继承了父类ParentClass的所有属性和方法,并且还可以添加自己的属性和方法。

        在Python中,可以通过将父类作为参数传递给子类来实现继承。子类将继承父类的属性和方法,并可以在需要时添加新的属性和方法。

        以下是一个简单的示例,演示了如何创建一个父类和一个子类,并通过继承获得父类的属性和方法:

# 定义父类
class Animal:
    def __init__(self, name, species):
        self.name = name
        self.species = species

    def make_sound(self):
        pass

# 定义子类,并继承父类Animal
class Dog(Animal):
    def __init__(self, name, breed):
        # 调用父类的构造函数
        super().__init__(name, species="Dog")
        self.breed = breed

    def make_sound(self):
        return "Woof!"

# 创建子类对象
dog = Dog("Buddy", "Labrador")
print(dog.name)  # 输出:Buddy
print(dog.species)  # 输出:Dog
print(dog.breed)  # 输出:Labrador
print(dog.make_sound())  # 输出:Woof!

在上面的示例中,我们定义了一个Animal父类,其中包含两个属性name和species,以及一个抽象方法make_sound。然后我们定义了一个Dog子类,并通过继承获得了父类Animal的属性和方法。在子类中,我们还添加了一个自己的属性breed,并实现了make_sound方法。通过继承,我们可以在子类中重用父类的代码,并且还可以扩展和定制子类的功能。 

2.2 方法的重写

        方法的重写(Method Overriding)是面向对象编程中的一个重要概念,它允许子类覆盖(重写)父类中已有的方法,从而实现对方法的定制和扩展。当子类中定义了一个与父类中同名的方法时,子类的方法将覆盖父类的方法,从而在子类对象中调用该方法时会执行子类中的实现而不是父类的实现。

        重写方法的基本语法如下:

class ParentClass:
    def some_method(self):
        # 父类的方法实现

class ChildClass(ParentClass):
    def some_method(self):
        # 子类重写的方法实现

在上面的语法中,我们定义了一个父类ParentClass,其中包含一个名为some_method的方法。然后我们定义了一个子类ChildClass,并在其中重新定义了some_method方法。当子类对象调用some_method方法时,将会执行子类的方法实现。

以下是一个示例,演示了如何在子类中重写父类的方法:

# 定义父类
class Animal:
    def make_sound(self):
        return "Some generic sound"

# 定义子类,并继承父类Animal
class Dog(Animal):
    def make_sound(self):
        return "Woof!"

# 创建子类对象
dog = Dog()
print(dog.make_sound())  # 输出:Woof!

在上面的示例中,我们定义了一个父类Animal,其中包含一个make_sound方法,它返回一个通用的声音字符串。然后我们定义了一个Dog子类,并在其中重写了make_sound方法,使其返回"Woof!"。当我们创建子类对象并调用make_sound方法时,将会执行子类Dog中重写的方法,输出"Woof!",而不是父类Animal中的实现。这就是方法重写的作用,它允许子类在需要的时候定制和扩展父类的方法。 

2.3 派生类中调用基类的_init_()方法

在派生类(子类)中调用基类(父类)的__init__()方法,可以通过使用super()函数来实现。super()函数是Python内置函数,它用于访问父类的方法和属性。

在派生类的__init__()方法中使用super()函数,可以在子类的构造函数中先调用父类的构造函数,然后再添加子类自己的初始化代码。这样可以确保子类对象在初始化时包含父类的属性。

下面是一个示例,演示了如何在子类中调用基类的__init__()方法:

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

class ChildClass(ParentClass):
    def __init__(self, name, age):
        super().__init__(name)  # 调用父类的__init__方法
        self.age = age

# 创建子类对象
child = ChildClass("Alice", 25)
print(child.name)  # 输出:Alice
print(child.age)   # 输出:25

在上面的示例中,我们定义了一个父类ParentClass,其中有一个__init__()方法,用于初始化name属性。

又定义了一个子类ChildClass,并在其__init__()方法中使用super().__init__(name)调用了父类的__init__()方法,从而在子类对象初始化时设置了name属性。

然后我们添加了子类自己的初始化代码,设置了age属性。最后,我们创建了子类对象并访问了nameage属性,验证了调用基类__init__()方法的正确性。

3 总结 

属性:

  • 属性用于存储数据或计算属性值,是类的成员之一。
  • 在类中可以通过在类体中声明变量来定义属性。属性可以是实例属性(属于类的实例)或类属性(属于类本身)。
  • 实例属性通过self关键字在类的方法中访问和修改,而类属性可以使用类名来访问。
  • 可以使用@property装饰器将方法转换为属性,从而实现属性的计算和访问控制。
  • 属性可以设置为私有的,通过在属性名前添加两个下划线__来实现私有属性。

继承:

  • 继承是面向对象编程中实现代码重用的机制,允许一个类(派生类)继承另一个类(基类)的属性和方法。
  • 派生类可以获得基类的所有属性和方法,并可以在派生类中添加新的属性和方法,或重写基类的方法。
  • 继承的关系形成了类的层次结构,子类继承了父类的特性,并可以进一步派生出更多的子类。
  • 使用继承可以减少代码的重复,提高代码的可维护性和可扩展性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/781335.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记录WordPress安装后我常用的插件

记录WordPress安装后我常用的插件 一、WordPress安装二、插件使用1.添加Astra主题2.Easy Updates Manager2.WP Githuber MD3.WP-Optimize – Cache, Clean, Compress4. WP-PostViews或Post Views Counter5. Easy Table of Contents5. UpdraftPlus Backup/Restore6.WP Super Cac…

【开源项目】低代码数据可视化开发平台-Datav

Datav 基本介绍 Datav是一个Vue3搭建的低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可完成业务需求。 它的技术栈为:Vue3 TypeScript4 Vite2 ECharts5 Axios Pinia2 在线预览 账号: admin 密码: 123123预…

4.1 Bootstrap UI 编辑器

文章目录 1. Bootstrap Magic2. BootSwatchr3. Bootstrap Live Editor4. Fancy Boot5. Style Bootstrap6. Lavish7. Bootstrap ThemeRoller8. LayoutIt!9. Pingendo10. Kickstrap11. Bootply12. X-editable13. Jetstrap14. DivShot15. PaintStrap 以下是 15 款最好的 Bootstrap…

Zabbix监控安装grafana并配置图形操作

第三阶段基础 时 间:2023年7月20日 参加人:全班人员 内 容: Zabbix监控安装grafana 目录 安装并配置grafana 一、安装Grafana 二、下载安装插件 三、配置grafana 四、Web访问并配置: 安装并配置grafana 一、安装Graf…

微服务之服务注册与发现原理

1. 前言 在传统的开发中,由于提供服务的地址是相对静态的,所以我们只需要找到对应服务的开发人员,然后了解到对应的服务接口地址就可以了。 而在微服务架构开发过程中,如果我们需要调用一个RESTFul风格的API接口,我们…

deep a wavelet 深度自适应小波网络

深度自适应小波网络 1.  原理说明 1.1 the Lifting scheme 提升方案,也称为第二代小波[25],是定义与第一代小波[6]具有相同属性的小波的一种简单而强大的方法。 提升方案将信号x作为输入, 生成小波变换的近似分量C, 和细节分量d 这两类…

网络安全基础知识解析:了解常见的网络攻击类型、术语及其防范方法

目录 1、网络安全常识和术语 1.1资产 1.2网络安全 1.3漏洞 1.4 0day 1.5 1day 1.6后门 1.7exploit 1.8攻击 1.9安全策略 1.10安全机制 1.11社会工程学 2、为什么会出现网络安全问题? 2.1网络的脆弱性 2.4.1缓冲区溢出攻击原理: 2.4.2缓冲…

NLP(六十一)使用Baichuan-13B-Chat模型构建智能文档问答助手

在文章NLP(六十)Baichuan-13B-Chat模型使用体验中,我们介绍了Baichuan-13B-Chat模型及其在向量嵌入和文档阅读上的初步尝试。   本文将详细介绍如何使用Baichuan-13B-Chat模型来构建智能文档问答助手。 文档问答流程 智能文档问答助手的流…

手机+App=电脑静音无线鼠标 - WiFimouse初体验

应用情景 大晚上的别人在睡觉,自己又不得不使用电脑(台式),鼠标点点点又吵。 专门买个静音鼠标又没钱,咋办~ 效果图 手机app 电脑无线触控板,零噪音! 可以单击、移动鼠标光标、可以上下滚动…

什么是Redis?

什么是Redis 什么是Redis一、特性1. 支持多种数据结构2. 读/写速度快,性能高。3. 支持持久化。4. 实现高可用主从复制,主节点做数据副本。5. 实现分布式集群和高可用。 二、基本数据类型string(字符串)list(双向链表)set(集合)zse…

22matlab数据分析 拉格朗日插值(matlab程序)

1.简述 第一部分:问题分析 (1)实验题目:拉格朗日插值算法 具体实验要求:要求学生运用拉格朗日插值算法通过给定的平面上的n个数据点,计算拉格朗日多项式Pn(x)的值,并将其作为实际函数f(x)的估…

文心千帆为你而来

1. 前言 3月16号百度率先发布了国内第一个人工智能大语言模型—文心一言。文心一言的发布在业界引起了不小的震动。而文心一言的企业服务则由文心千帆大模型平台提供。文心千帆大模型平台是百度智能云打造出来的一站式大模型开发与应用平台,提供包括文心一言在内的…

文件被识别为病毒,被删除,如何解决

我们的文件有时候有用,但是电脑却识别为病毒,直接给我删除掉了,这让人是真的很XX,那该怎么办呐。 我最近用了这个方法很多次,蛮好用,分享给大家! 1、先找到安全中心 2、找不到排除项 3、点击添…

工程矩阵理论复习线路推荐

文章目录 写在前面复习线路推荐前期中期后期其他资料 写在前面 本篇博客仅适用于东南大学研究生 工程矩阵理论科目复习 对不少人来说,研究生的课程成绩相较于本科成绩不是那么重要了。但是由于工程矩阵还是比较有难度的,又很长时间没接触过数学&#x…

7-22练习

题目1 链接5071 不难发现通过A的范围可以缩小B的范围进而减少循环次数 通过B可以消除A的循环 这个是一个很巧妙的地方。这个题还有一个比较容易引起歧义的地方就是i:n每一次循环都要符合条件 这样我们不难构造出一个函数 f(B+x) = 1000*A+x 试验1 运行超时-- 需要减少复杂度…

时钟分频器

文章目录 一、8分频二、n倍时钟分频器 一、8分频 8倍时钟分频器是一种电路或设备,用于将输入时钟信号的频率分成原来的1/8。它可以在数字电子系统中用于将高频时钟信号降低到较低的频率,以满足特定的系统需求。 在这个电路中,CLK是输入的时钟…

【晓风残月】byte,short,int,long——八种基本类型

文章目录 前言废话不多说,总结下今天的成果以及踩的坑 一、第一个坑【数据丢失】二、第二个坑【byte集合无法转换byte数组】三、第三个坑【Byte[]转byte[]】四、第四个坑【16进制转byte】总结快一年没写博客了,貌似都不记得过去的自己了向前看&#xff1…

Camtasia2023电脑录屏视频自动生成字幕软件

制作视频通常需要添加字幕,添加字幕比较麻烦的是让字幕和声音同步,使用好的软件可以大大提高剪辑效率,让视频更快制作完成。本文将给大家介绍录制视频自动生成字幕的软件设置字幕语音同步教程。 一、录屏视频自动生成字幕的软件 Camtasia是…

查询优化之“查询分离”

什么业务场景需要使用查询分离 当数据在任何时候都可能被修改和查询的场景下,就不适合采用冷热分离来解决问题。而读写分离方案得到的工单查询速度提升是有限的,它主要还是用在数据库高并发的场景中。查询分离可以有效提升数据的查询效率,即…

【Ajax】笔记-JQuery发送请求与通用方法

Get请求 语法格式: $.get(url, [data], [callback], [type]) url:请求的 URL 地址。data:请求携带的参数。callback:载入成功时回调函数。type:设置返回内容格式,xml, html, script, json, text, _default。 准备三个按钮分别测试Get 、Post、通用型方…