Python基础6——面向对象

14 面向对象

14.1 面向对象基础

​ 面向对象是一种编程思想,处理面向对象编程以外,还有面向过程编程

三大特征:

11. 封装 22. 继承 33. 多态

面向过程与面向对象的区别

  1. 面向过程: 自己动手洗衣服,拧衣服、晾衣服
  2. 面向对象:构造一个洗衣机对象,让洗衣机对象完成

14.2 类和对象

:相同属性和功能的一类事物。

​ 人是一个,张三(对象),李四(对象),王五(对象)

​ 狗是一个,张三的柯基(对象),张三的哈士奇(对象),王五的田园犬(对象)

类的写法

1class 类名: 2 pass 3 4# 一般首字母大写,使用驼峰命名法。

​ 类的三要素

  1. 类名
  2. 属性
  3. 方法
1 2class Human: 3 hair = 'gold' 4 5print(Human.hair) 6Human.hair = 'black' 7print(Human.hair) 8Human.name = '比尔盖茨' 9del Human.hair #删除属性 10

实例化对象

执行实例方法时,自动将调用该方法的对象赋值给self

1# 实例化对象的格式: 对象名 = 类名() 2# 实例方法:由对象来调用,至少一个self参数; 3# 执行实例方法时,自动将调用该方法的对象赋值给self 4 5class Person: 6 name = "zhangsan" 7 def speak(self): 8 print("self") 9 print(self) #这里的self就是当前调用函数的对象 10 print("正在说话") 11 12 13p1 = Person() 14print(p1) 15 16p1.speak() 17

14.3 构造方法

实例属性: self.属性名

1 2class A: 3 name = 'zhangsan' #类属性 4 5 def work(self): #实例方法 6 print("实例方法") 7 print(f"张三的年龄是{self.age}") 8 9a = A() 10a.age = 20 11a.work() 12

构造方法

类在实例化的时候,会自动执行init方法

1 2class A: 3 def __init__(self,name): 4 self.name = name 5 6a = A("张三") 7print(a.name) 8
1 2class Hero: 3 def __init__(self,name,hp,at): 4 self.name = name 5 self.hp = hp 6 self.at = at 7 8 def move(self): 9 print(f"{self.name}在移动") 10 def attack(self): 11 print(f"{self.name}的生命值是{self.hp}") 12 13 # 实例化对象 14libai = Hero("李白",2000,120) 15libai.move() 16libai.attack() 17 18luban = Hero("鲁班",2100,200) 19luban.move() 20luban.attack() 21

14.4 类属性和实例属性

总结:

  1. 类属性属于类,实例属性属于对象

  2. 实例属性属于每个对象,对象不同实例属性不同。实例属性需要添加self

1class A: 2 num = 10 #类属性 3 def __init__(self,name): 4 self.name = name #实例属性 5 def test(self): 6 print(f"我是{self.name}") 7 8 9# 第一次实例化对象 10a = A("张三") 11a.test() 12print(A.num) #通过类名查看类属性 13print(a.num) #通过对象查看类属性 14print(a.name) #通过对象查看实例属性 15 16# 第二次实例化对象 17a1 = A("李四") 18a1.test() 19print(a1.name) 20print(a1.num) 21 22

14.5 析构方法

当对象被垃圾回收的时候,解释器会默认调用del的方法。

1class A: 2 def __del__(self): 3 print("执行析构方法") 4a = A() 5print("打印最后一句") 6 7# 运行结果 8# 打印最后一句 9# 执行析构方法 10
1class A: 2 def __del(self): 3 print("执行析构方法") 4a = A() 5del p 6print("打印最后一句") 7 8# 运行结果 9# 执行析构方法 10# 打印最后一句 11 12

14.6 封装

14.6.1 封装的概念

将复杂的信息、流程给包起来,内部处理,让使用者只需要通过简单的操作步骤,就能实现。

封装的概念:

  1. 类 ,本身就是一种封装
  2. 类中定义私有,只在类的内部使用,外部无法访问

14.6.2 私有属性

​ 私有权限:在属性名和方法名前加上两个下划线

1class Person: 2 name = "jiuge" #类属性 3 __age = 18 #类的私有属性 4 5 6a = Person() 7print(a.name) 8print(a.__age) #会报错 9# 私有属性:外部不能直接访问 10 11# 如何访问私有属性,不建议使用 12# 第一种方式 13# _类名__属性名 14print(pe._Person__age) 15 16# 第二种方式 17class Person: 18 name = "jiuge" 19 __age = 18 20 21 def getAge(self): #获得私有属性的方法 22 return Person.__age 23 24pe = Person() 25print(pe.getAge()) 26 27

14.6.3 私有方法、proteted方法

_xx : 单下划线开头,protected属性/方法,在对象和子类可以访问,其实并没有什么卵用

__xx : 双下划线开头,私有权限,无法在外部直接访问

1class Person: 2 name = "jiuge" #类属性 3 _sex = '女' #protected方法 4 __age = 18 # 私有属性 5a = Person() 6 7print(a._sex) #可以访问 8print(a.__age) #不可以访问

私有方法

双下划线开头

1class Human: 2 def __play(self): #私有方法 3 print("玩手机") 4 5 def funa(self): #实例方法 6 # 不推荐 7 # Human.__play(self) #在实例方法中调用私有方法 8 9 self.__play() #直接用这个就可以了 10 11ha = Human() 12ha.__play() #会报错 13ha.play() #会报错 14ha.funa() 15

14.7 继承(单继承、多继承)

14.7.1 单继承的例子

继承可以使子类具有父类的所有属性和方法

语法:class 类名(父类名)

1class A: 2 def __init__(self): 3 self.age = 18 4 def add(self): 5 print(self.age+10) 6 7class B(A): #B类继承A类 8 pass 9 10b = B() 11print(b.age) 12b.add() 13
1 2class Animals: #父类 3 def eat(self): 4 print("吃") 5 def sleep(self): 6 print("睡") 7 8class Pig(Animals):#子类 9 pass 10 11class Dog(Animals): #子类 12 pass 13 14pig = Pig() #实例化子类 15pig.eat() 16pig.sleep() 17 18dog = Dog() #实例化子类 19dog.eat() 20dog.sleep() 21 22

14.7.2 单继承的传递性

如果C类(子类)继承于B类(父类),B类(子类)继承于A类(父类)

那么C类具有A类、B类的属性和方法

1 2class A: 3 def eat(self): 4 print("吃") 5 def sleep(self): 6 print("睡") 7 8class B(A): #继承于A类 9 def study(self): 10 print("学习") 11 12class C(B): #继承于B类 13 pass 14 15b = B() 16b.eat() 17b.study() 18 19 20c = C() 21c.study() #调用父类的方法 22c.eat() #调用父类的父类的方法 23

14.7.3 多继承

python中内置属性__mro__可以查看方法搜索顺序

确定子类对象调用方法的顺序

1print(Son.__mro__) 2 3# 打印执行方法的顺序 4print(C.__mro__)

子类拥有所有父类的属性和方法

1class A: 2 def eat(self): 3 print("吃") 4 5class B: 6 def sleep(self): 7 print("睡") 8class C(A,B): #C多继承A类和B类 9 pass 10 11c = C() 12c.eat() 13c.sleep()

若D类继承于A类、B类

则D会先找A类中的方法,如果找不到再找B类的方法

1class A: 2 def h(self): 3 print("a") 4class B: 5 def h(self): 6 print("c") 7 8class C(A,B): 9 pass 10 11c = C() 12c.h() 13# 输出结果 14# a 15 16class D(B,A): 17 pass 18# 输出结果 19# c 20

查找顺序 D->A->B->C

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y3SN4NnR-1625891783101)(https://img2020.cnblogs.com/blog/1466380/202006/1466380-20200604210907285-1409082663.png)]

查找顺序D->B->A->C

查找顺序E->B->A->D->C

s

查找顺序 E->B->A->D->C->F

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DH3Pofj4-1625891783106)(https://img2020.cnblogs.com/blog/1466380/202006/1466380-20200604212718837-1012657606.png)]

14.7.4 继承的例子

奥特曼的例子

1#奥特曼 2 3# 一代产品 4class Aoteman(object): 5 def __init__(self,year,name): 6 self.year = year 7 self.name = name 8 9 def speak(self): 10 print(f"{self.name}说,爱是一道光") 11 12 def attack(self): 13 print(f"{self.year}年的{self.name}会发光") 14 15at = Aoteman(1996,"初代奥特曼") 16at.speak() 17at.attack() 18 19 20# 二代奥特曼 21class Aoteman2(Aoteman): #继承一代奥特曼的特性 22 def attack(self): 23 print(f"{self.year}年的{self.name}会投飞镖") 24 25at2 = At2(1998,"赛文") 26at2.speak() 27at2.attack() 28 29 30# 三代奥特曼 31class At3(object): 32 33 def defend(self): #防御 34 print("会躲避怪兽的攻击") 35 36class Aoteman3(Aoteman,At3): #多继承 37 def attack(self): 38 print(f"{self.year}年的{self.name}奥特曼会光之射线") 39 40 def color(self): 41 print(f"{self.name}奥特曼会变色") 42 43at3 = Aoteman3(2000,'迪迦') 44at3.speak() 45at3.attack() 46at3.color() 47at3.defend() 48

14.8 重写

子类继承父类的方法和属性,对父类的方法和属性进行重写

14.8.1 覆盖父类方法

​ 在子类中定义一个跟父类同名的方法

1 2class Person:#父类 3 def work(self): 4 print("接受社会的考验") 5 6class Son(Person): #子类 7 def work(self): 8 print("接受社会的毒打") 9 10son = Son() 11son.work() 12# 运行结果 13# 接受社会的毒打 14 15

14.8.2 对父类的方法进行扩展:

继承父类的方法,子类可以增加自己的功能

实现方法

  1. 父类名.方法名(self)
  2. super().方法名()

父类名.方法名(self)

1 2class Person: 3 def work(self): 4 print("接受社会的考验") 5class Son(Person): 6 def work(self): 7 Person.work(self) 8 print("接受社会的毒打") 9 10son = Son() 11son.work()

super().方法名()

super是一个特殊的类,super()是使用super类创建出来的对象,可以调用父类中的方法

1 2class Animal: 3 def __init__(self,name): 4 self.name = name 5 6 def bark(self): 7 print(f'{self.name}在叫') 8 9class Dog(Animal):#子类 10 def bark(self): 11 super().bark() #父类的方法 12 print(f"{self.name}在汪汪叫") #在父类的方法上进行扩展 13 14dog = Dog('哈士奇') 15dog.bark()

14.8.3 多继承中的重写

多继承的重写,根据广度优先搜索进行执行

14.9 新式类写法,object类

1# 写法一 2class A: 3 pass 4# 写法二 5class A(): 6 pass 7# 写法三,推荐 8class A(object): 9 pass

object是为所有对象提供的基类,提供了一些内置的属性和方法

14.10 多态

14.10.1 多态基础

python中的多态是一个<font color="red">伪多态</font>

​ 一个对象具有多种形态,在不同的使用环境中以不同的形态展示其功能,那么我们就称该对象具有多态特性。

多态发生在具有继承关系的基础之上

不关注对象的类型,关注对象具有的行为

不同的子类对象,调用相同的父类方法,会产生不同的执行结果

1 2# + 同样的+号,不同的对象使用,就会有不同的结果 3print(10+10) 4print("10"+"10") 5
1class Animal(object): 2 def walk(self): 3 print("动物在走路") 4 5class Cat(Animal): 6 def walk(self): 7 print("走猫步") 8miao = Cat() 9miao.walk() 10# 输出结果 11# 走猫步 12 13class People(Animal): 14 def walk(self): 15 print("两条腿走路") 16people = People() 17people.walk() 18# 输出结果 19# 两条腿走路 20

14.10.2 多态性

一种调用方式,不同的执行结果

指具有不同功能的函数可以使用相同的函数名,把对象作为参数传入

1class A(object): #父类 2 def speak(self): 3 print("群众的眼睛是雪亮的") 4 5class C1(A): #子类1 6 def speak(self): 7 print("年轻人不讲武德") 8 9class C2(A): #子类2 10 def speak(self): 11 print("心疼giegie") 12 13def test(obj): #定义一个函数,把对象作为参数传入 14 obj.speak() 15 16c1 = C1() 17# c1.speak() 18test(c1) 19# 输出结果 20# 年轻人不讲武德 21 22c2 = C2() 23# c2.speak() 24test(c2) 25# 输出结果 26# 心疼giegie 27

14.11 类方法和静态方法

实例方法:方法内部访问实例属性,方法内部可以通过类名.类属性来访问类属性

静态方法:方法内部,不允许访问实例属性,类属性可以通过类名调用。<font color="red">但是不推荐这么使用</font>

类方法:方法内部只允许访问类属性,通过cls.类属性访问

14.11.1 静态方法

使用@staticmethod符号进行定义

1class 类名: 2 @staticmethod #定义为静态方法 3 def 方法名(形参): 4 方法体 5# 调用格式 6类名.方法名(参数) 7对象名.方法名(参数) 8
1 2class Dog(object): 3 4 @staticmethod #静态方法:类中的函数。可以用类名调用类属性,但是不推荐。 5 def run(): 6 print("狗狗在跑步") 7 8Dog.run()

14.11.2 类方法

使用@classmethod符号进行定义

针对类对象定义的方法

1class 类名 2 @classmethod #类方法 3 def 方法名(cls): #出现cls参数 4 方法体 5
1class Cat(object): 2 name = '布偶' #类属性 3 4 @classmethod #类方法 5 def sleep(cls): #这里的cls是指Cat这个类 6 print(cls) 7 print("猫猫在睡觉") 8 9print(Cat) 10Cat.sleep() 11# 输出结果 12# <class '__main__.Cat'> 13# <class '__main__.Cat'> 14# 猫猫在睡觉 15

14.12 魔法方法

魔法方法有很多,这里只举4个例子

1__doc__ #类的描述信息 2__module__ #表示当前操作的对象在哪个模块 3__class__ # 表示当前操作的对象的类是什么 4__str__ #对象的描述信息

14.12.1 __doc__方法

1 2class A: 3 ''' 4 这是类的描述信息 5 ''' 6 # 必须要使用'''来表示 7 pass 8 9print(A.__doc__) 10 11# 这是类的描述信息

14.12.2 __str__方法

1# 如果类中定义了__str__方法,那么在打印实例化对象,默认输出该方法的返回值 2 3# str方法必须返回一个字符串 4class A: 5 def __str__(self): 6 return "类似于java的toString方法" 7a = A() 8print(a) 9

14.12.3 __module__ 、__class__ 方法

1pytest.py 2class C: 3 def funa(self): 4 print("这是C类的实例方法") 5 6 7main.py 8import pytest 9pt = pytest.C() 10print(pt) 11pt.funa() 12 13print(pt.__module__) #输出结果: pytest 所在模块 14print(pt.__class__) #<class 'pytest.C'> 15 16

14.12.4 __eq__

判断两个类是否相等,返回bool值

14.12.4 __hash__

点赞
收藏

评论区

加载中...

相关推荐

什么是面向对象编程?

原文链接:什么是面向对象编程?面向对象程序设计(ObjectOrientedProgramming,OOP)是一种计算机编程架构,也可以理解为是一种编程的思想。面向对象程序设计的核心就是对象和类,对象也是类的实例化,类是对现实对象的抽象。对象间通过消息传递

java面试考点解析(4):面向对象思想、系统架构设计

\ 一、面向对象思想 \1、面向对象的特征有哪些方面?答:面向对象的特征主要有以下几个方面:\抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象

java

2、面向对象(封装)面向对象思想:面向对象是基于面向过程的编程思想。面向过程:强调每一个功能的步骤面向对象:强调的是对象,然后用对象去调用功能特点A:符合我们思考习惯的思想

从一个 10 年程序员的角度告诉你:搞懂 Java 面向对象有多容易?

前言:1)java面向对象语言,面向过程围绕过程(解决问题步骤),面向对象围绕实体(名词,特性(属性),行为(动作、方法))。它们设计思想区别在于关心核心不同的。主流都是面向对象的。实际开发,先按面向对象思想进行设计,具体实现时面向过程(人习惯)2)java怎么支持面向对象呢?a.万物皆对象,所有的类都是Object子类b.java中支

Python入门之类(class)

Python3面向对象Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对

Python入门之类(class)

Python3面向对象Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对