Python面向对象专题(面向对象,类,特殊方法,封装,继承,多态

本文介绍了Python面向对象编程中的关键概念,包括属性和方法的定义与访问,self参数的作用,特殊方法(如__init__),封装(私有属性和隐藏属性)、getter和setter函数,property装饰器,继承机制,方法重写和super(),以及多态的含义和应用。
摘要由CSDN通过智能技术生成

输出结果:

在这里插入图片描述

2.3 属性和方法


2.3.1 小引

  • 一个对象可以分为两部分:①属性②方法

  • 在类代码快中,我们可以定义变量和函数:

变量会成为该类实例的公共属性,所有的该类的实例都可以通过 对象.属性名的形式访问。

函数会成为该类实例的公共方法,所有的该类的实例都可以通过 对象.方法名的形式访问。

2.3.2 属性

  • 类对象是可以添加属性的,语法为:对象.属性名 = 属性值

  • id和type是每个对象自带的属性,即存储。对象一被创建,就有id和type属性。

print(id(mc), id(mc1))

输出结果如下:

在这里插入图片描述

print(type(mc))

输出结果如下:

在这里插入图片描述

2.3.3 方法

  • 调用方法语法:对象.方法名()

  • 方法调用 和 函数调用 的区别:

如果是函数调用,调用的时候有几个形参,就会传入几个实参。

如果是方法调用,默认传递一个参数。所以方法中至少得有一个形参。

2.4 self参数


  • self 在定义的时候需要定义,但是在调用时会自动传入。

  • self 的名字并不是规定死的,但是是约定俗成的。所以一般最好使用self,而不是别的。

  • self总是指调用时类的实例。

现举代码实例如下:

class Person():

name = ‘张三’

age = 18

identity = ‘学生’

def speak(self): # self就等于任何调用我这个方法的对象本身

print(‘你好,我是{},{}岁的{}’.format(self.name, self.age, self.identity))

p1 = Person()

p1.name = “马保国”

p1.age = 65

p1.identity = ‘老同志’

p1.speak()

输出结果:

在这里插入图片描述

3. 特殊方法

==============================================================================

在类中可以定义一些形如__xxx__的方法,称为特殊方法,也称魔术方法。特殊方法不需要我们调用,会在特定的时候自动调用。

  • 掌握下边这种定义类写法,方可实现在创建类的实例对象的时候直接传入属性。

class Person():

name = ‘张三’

age = 18

identity = ‘学生’

特殊方法 init,类的对象被创建时, __init__就会被调用

def init(self, name, age, identity):

self.name = name

self.age = age

self.identity = identity

print(‘hello’) # 实例对象一被创建,"hello"就被输出。

这样写,再创建类的对象的时候,name和age都将成为必传参数。缺少则 __init__会无法运行,导致报错。

这里不能用不定长参数,那样没有任何意义。

def speak(self): # self就等于任何调用我这个方法的对象本身

print(‘你好,我是{},{}岁的{}’.format(self.name, self.age, self.identity))

p1 = Person(“马保国”, 65,“老同志”)

p1.speak()

在这里插入图片描述

4.封装

==========================================================================

4.1封装,私有属性,隐藏属性


封装是面向对象三大特征之一。我们需要一种方式来增强数据的安全性,这种方式就是封装。

封装是指隐藏对象中一些不希望被外部访问到的属性或方法。具体方式为,在属性名前加入一个下划线,表示不可直接访问,但仍可手动访问,只是提醒不可修改;在属性名前加两个下划线表示隐藏属性。

示例:

class Person():

def init(self, name, age, identity):

self.name = name

self._age = age

self.__identity = identity

这样写,再创建类的对象的时候,name和age都将成为必传参数。缺少则 __init__会无法运行,导致报错。 # 这里不能用不定长参数,那样没有任何意义。

def speak(self): # self就等于任何调用我这个方法的对象本身

print(‘你好,我是{},{}岁的{}’.format(self.name, self._age, self.__identity))

p1 = Person(“马保国”, 65,“老同志”)

print(p1.name)

print(p1.age)

print(p1.identity)

运行结果如下:

在这里插入图片描述

我们可以看到,name依然可以直接访问,但是前边加了一个下划线的age和加了两个下划线的identity属性已经不能直接访问了。


  • 对于前边加了一个下划线的属性age,我们使用p1._age的方式依然可以访问age属性的。

在这里插入图片描述

但是对于前边加了两个下划线的属性identity,我们却不能再使用p1.__identity来访问了。否则会有如下报错。

在这里插入图片描述

  • 但是对于这样的属性,并不是没有办法访问。

我们可以使用固定语法:_类名__属性名 的形式进行访问。

如 p1._Person__identity

(类名前加一个下划线,类名与属性名之间加了两个下划线)

即:

在这里插入图片描述

这样就访问成功了。

  • 该如何解释这一系列情况呢?

可以这样来理解。

  • 一般情况下,加_的都是私有属性。没有特殊情况下不要修改私有属性。封装就是这样保障数据安全的。这种”不要修改“是一种约定俗成,不意味着不能修改,只是对编程者的一种提醒。毕竟所有的属性,只要你想修改,都还是受人为控制的。

  • 加一个_后,只是相当于传入属性值后,把原先的属性名前加了一个下划线,故可以通过“_属性名”的形式访问。

  • 而对于加了__(两个下划线)的隐藏属性,本质上只不过是Python自动为属性改了一个名字,即 _类名__属性名 。这样我们就常常把它描述为“私有属性不能通过对象来获取,只能在类的内部访问。” (一句常见的概述)但是,上边的例子我们也看到了,使用p1._Person_identity的方式确实可以说是通过对象访问到了属性值。但是这句话本身是没有问题的,之所以这么说,就是我们对于封装这一概念的一种认同与使用,我们约定俗成不乱操作封装过的属性值,以保障数据安全,我们只是不再可以通过原来的对象名字来获取该对象了。

  • 协定开发我们一般使用私有属性(一个下划线),而一般不用隐藏属性。


4.2 getter()与setter()


我们也可以给类提供上getter()和setter()方法

getter() 用于获取对象中指定的属性

setter() 用于设置对象中的属性

示例如下:

class Person():

def init(self, name, age, identity):

self.name = name

self.__age = age

self._identity = identity

getter方法 提供给你访问这个属性的方法 # 协定开发一般用 私有属性

def get_identity(self):

return self._identity

setter方法 提供给你修改这个属性的方法

def set_identity(self, identity):

self._identity = identity

def speak(self):

print(‘你好,我是{},{}岁的{}’.format(self.name, self.__age, self._identity))

逐句输入下边代码,观察结果,以感受其用法逻辑。

p1 = Person(“马保国”, 65,“老同志”)

p1.get_identity()

p1.speak()

p1.set_identity(‘武林高手’)

p1.get_identity()

p1.speak()

结果展示如下:

在这里插入图片描述

  • 增加getter()和setter()方法,可以很好地控制属性是否是只读的。

5. property装饰器

=====================================================================================

我们可以用@property装饰器来创建只读属性,@property装饰器会将方法转换为相同名称的只读属性,可以与所定义的属性配合使用,这样可以防止属性被修改。

具体示例如下:

class Person():

这里,name属性是私有属性,不可读也不可改

def init(self, name):

self._name = name

getter方法 提供给你访问这个属性的方法

@property

def name(self):

return self._name

这样,name属性就转为了只读,不可改。可以通过相同名称的方法:name来查看name属性。

如果想再把不可改的属性改为可改属性,则:

setter方法 提供给你修改这个属性的方法

@name.setter

def name(self, name):

self._name = name

下边 逐句进行测试

p1 = Person(‘马保国’)

print(p1.name) # 可以通过p1.name 读取name属性了。

p1.name = ‘蔡徐坤’ # 可以这样修改p1的name属性了。

print(p1.name) # name属性已被更改


6. 继承

============================================================================

6.1 继承概述 与 object类


继承也是面向对象的三大特征之一,通过继承我们可以使一个类获取到其他类中的属性和方法。

在定义类的时候,可以在类名后边的括号中指定当前类的父类

继承提高了类的复用性,让类与类之间有了关系,有了这个关系,才有了多态的特性。

定义一个父类

class Person(object):

def init(self, name):

self.name = name

定义一个子类

class boy(Person):

def speak(self):

print(‘He has a dream.’)

这就实现了一个简单的类的继承。

issubclass()方法 用于检测一个类是否是一个类的父类

print(issubclass(boy, Person)) # True

print(issubclass(Person, object)) # True

对于父类,或者说是不继承其他类的独立的类,定义的时候我们约定俗成继承object这个类,object类中有很多高级特性可以使用。不过即使不传入object也没有关系,我们创建类的时候python3已经默认帮我们传入了object。object类是所有类中最大的父类。

对于子类,则必须要在其括号中填入要继承的父类。

6.2 方法重写


  • 方法重写要建立在继承的基础之上。

  • 如果在子类中有和父类同名的方法,则通过子类实例对象区调用方法时,会调用的是子类的方法,而不是父类的方法,这个特点我们称之为方法的重写(覆盖)。

  • 当我们调用一个对象的方法时,会优先在当前对象的类中寻找,有则直接调用,没有则去当前对象的类的父类中寻找,有则调用,没有则继续往上边的父类中寻找,以此类推。直到找到object类,如果还没有就报错了。

可以通过这段示例代码来体会其逻辑:

class A(object):

name = ‘A’

def test(self):

print(‘A…’)

class B(A):

def test(self):

print(‘B,…’)

class C(B):

pass

c = C()

逐句测试

c.test()

print(c.name)


6.3 super()方法


  • super这个方法的使用时建立在两个基础之上的
  1. 必须要有父类的继承

  2. 必须要有方法的重写

super()方法可以获取到当前类的父类的方法。且通过super()方法返回对象调用父类方法时,不需要调用self。

class A(): # 默认继承object

def test(self):

print(‘A…’)

class B(A):

def test(self):

print(‘B,…’)

super的作用: 将被覆盖了的父类方法,重新调用

def test2(self):

super().test()

进行逐行测试

b = B()

b.test()

b.test2()

结果如下:

在这里插入图片描述

这样,就既能使用子类中的test方法,也能调用父类中的test方法了。


6.4 多重继承


  • python是支持多重继承的,也就是说我们可以为一个类同时指定多个父类。只要在子类后边的括号里添加多个类即可实现多重继承。

  • 多重继承可以使子类同时拥有多个父类,并且会获取到所有父类中的方法,如果遇到调用父类中的同名方法,则按照括号内传入的顺序,会先在第一个父类中寻找,然后是第二个,第三个…以此类推,前边的会覆盖后便的。

  • 在开发者如果没有特殊要求,应尽量避免使用多重继承。多重继承会使得我们的代码更加复杂。

简要写法示例:

class A():

def test(self):

print(‘A…’)

class B():

def test(self):

print(‘B…’)

class C(A, B): # 这样就实现了C类对A类和B类的多重继承。

def speak(self):

print(‘A和B都是我爹。’)

调用test方法的话,按先后顺序会调用A中的,B中的test()方法会被覆盖。

c = C()

c.test()

输出结果:

在这里插入图片描述


7. 多态

============================================================================

多态是面向对象三大特性之一。从字面来理解,就是指多种形态。

python中多态的特点:

  1. python中的多态只关心对象的实例方法是否同名,不关心对象所属的类型。

  2. 对象所属的类之间,继承关系也是可有可无的。

  3. 多态可以增加代码外部调用的灵活度,让代码更通用,兼容性比较强。

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 12
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值