Python基础6——面向对象

半臻
• 阅读 2344

14 面向对象

14.1 面向对象基础

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

三大特征:

1. 封装
2. 继承
3. 多态

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

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

14.2 类和对象

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

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

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

类的写法

class 类名:
    pass

# 一般首字母大写,使用驼峰命名法。

​ 类的三要素

  1. 类名
  2. 属性
  3. 方法

class Human:
    hair = 'gold'

print(Human.hair)
Human.hair = 'black'
print(Human.hair)
Human.name = '比尔盖茨'
del Human.hair  #删除属性

实例化对象

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

# 实例化对象的格式: 对象名 = 类名()
# 实例方法:由对象来调用,至少一个self参数;
# 执行实例方法时,自动将调用该方法的对象赋值给self

class Person:
    name = "zhangsan"
    def speak(self):
        print("self")
        print(self) #这里的self就是当前调用函数的对象
        print("正在说话")


p1 = Person()
print(p1)

p1.speak()

14.3 构造方法

实例属性: self.属性名


class A:
    name = 'zhangsan' #类属性

    def work(self): #实例方法
        print("实例方法")
        print(f"张三的年龄是{self.age}")

a = A()
a.age = 20
a.work()

构造方法

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


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

a = A("张三")
print(a.name)

class Hero:
    def __init__(self,name,hp,at):
        self.name = name
        self.hp = hp
        self.at = at

    def move(self):
        print(f"{self.name}在移动")
    def attack(self):
        print(f"{self.name}的生命值是{self.hp}")

 # 实例化对象
libai = Hero("李白",2000,120)
libai.move()
libai.attack()

luban = Hero("鲁班",2100,200)
luban.move()
luban.attack()

14.4 类属性和实例属性

总结:

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

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

class A:
    num = 10 #类属性
    def __init__(self,name):
        self.name = name #实例属性
    def test(self):
        print(f"我是{self.name}")


# 第一次实例化对象
a = A("张三")
a.test()
print(A.num)  #通过类名查看类属性
print(a.num)  #通过对象查看类属性
print(a.name)  #通过对象查看实例属性

# 第二次实例化对象
a1 = A("李四")
a1.test()
print(a1.name)
print(a1.num)

14.5 析构方法

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

class A:
    def __del__(self):
        print("执行析构方法")
a = A()
print("打印最后一句")

# 运行结果
# 打印最后一句
# 执行析构方法
class A:
    def __del(self):
        print("执行析构方法")
a = A()
del p
print("打印最后一句")

# 运行结果
# 执行析构方法
# 打印最后一句

14.6 封装

14.6.1 封装的概念

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

封装的概念:

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

14.6.2 私有属性

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

class Person: 
    name = "jiuge" #类属性
    __age = 18  #类的私有属性


a = Person()
print(a.name)
print(a.__age) #会报错
# 私有属性:外部不能直接访问

# 如何访问私有属性,不建议使用
# 第一种方式
# _类名__属性名
print(pe._Person__age)

# 第二种方式
class Person:
    name = "jiuge"
    __age = 18

    def getAge(self): #获得私有属性的方法
        return Person.__age

pe = Person()
print(pe.getAge())

14.6.3 私有方法、proteted方法

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

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

class Person:
    name = "jiuge" #类属性
    _sex = '女'   #protected方法
    __age = 18    # 私有属性
a = Person()

print(a._sex) #可以访问
print(a.__age) #不可以访问

私有方法

双下划线开头

class Human:
    def __play(self): #私有方法
        print("玩手机")

    def funa(self):  #实例方法
        # 不推荐
        # Human.__play(self)  #在实例方法中调用私有方法

        self.__play() #直接用这个就可以了

ha = Human()
ha.__play() #会报错
ha.play() #会报错
ha.funa()  

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

14.7.1 单继承的例子

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

语法:class 类名(父类名)

class A:
    def __init__(self):
        self.age = 18
    def add(self):
        print(self.age+10)

class B(A): #B类继承A类
    pass

b = B()
print(b.age)
b.add()

class Animals: #父类
    def eat(self):
        print("吃")
    def sleep(self):
        print("睡")

class Pig(Animals):#子类
    pass

class Dog(Animals): #子类
    pass

pig = Pig() #实例化子类
pig.eat()
pig.sleep()

dog = Dog() #实例化子类
dog.eat()
dog.sleep()

14.7.2 单继承的传递性

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

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


class A:
    def eat(self):
        print("吃")
    def sleep(self):
        print("睡")

class B(A): #继承于A类
    def study(self):
        print("学习")

class C(B): #继承于B类
    pass

b = B()
b.eat()
b.study()


c = C()
c.study() #调用父类的方法
c.eat()  #调用父类的父类的方法

14.7.3 多继承

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

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

print(Son.__mro__)

# 打印执行方法的顺序
print(C.__mro__)

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

class A:
    def eat(self):
        print("吃")

class B:
    def sleep(self):
        print("睡")
class C(A,B): #C多继承A类和B类
    pass

c = C()
c.eat()
c.sleep()

若D类继承于A类、B类

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

class A:
    def h(self):
        print("a")
class B:
    def h(self):
        print("c")

class C(A,B):
    pass

c = C()
c.h()
# 输出结果
# a

class D(B,A):
    pass
# 输出结果
# c

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

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

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

Python基础6——面向对象

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

Python基础6——面向对象

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

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

14.7.4 继承的例子

奥特曼的例子

#奥特曼

# 一代产品
class Aoteman(object):
    def __init__(self,year,name):
        self.year = year
        self.name = name

    def speak(self):
        print(f"{self.name}说,爱是一道光")

    def attack(self):
        print(f"{self.year}年的{self.name}会发光")

at = Aoteman(1996,"初代奥特曼")
at.speak()
at.attack()


# 二代奥特曼
class Aoteman2(Aoteman): #继承一代奥特曼的特性
    def attack(self):
        print(f"{self.year}年的{self.name}会投飞镖")

at2 = At2(1998,"赛文")
at2.speak()
at2.attack()


# 三代奥特曼
class At3(object):

    def defend(self): #防御
        print("会躲避怪兽的攻击")

class Aoteman3(Aoteman,At3): #多继承
    def attack(self):
        print(f"{self.year}年的{self.name}奥特曼会光之射线")

    def color(self):
        print(f"{self.name}奥特曼会变色")

at3 = Aoteman3(2000,'迪迦')
at3.speak()
at3.attack()
at3.color()
at3.defend()

14.8 重写

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

14.8.1 覆盖父类方法

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


class Person:#父类
    def work(self):
        print("接受社会的考验")

class Son(Person): #子类
    def work(self):
        print("接受社会的毒打")

son = Son()
son.work()
# 运行结果
# 接受社会的毒打

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

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

实现方法

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

父类名.方法名(self)


class Person:
    def work(self):
        print("接受社会的考验")
class Son(Person):
    def work(self):
        Person.work(self)
        print("接受社会的毒打")

son = Son()
son.work()

super().方法名()

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


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

    def bark(self):
        print(f'{self.name}在叫')

class Dog(Animal):#子类
    def bark(self):
        super().bark()  #父类的方法
        print(f"{self.name}在汪汪叫")  #在父类的方法上进行扩展

dog = Dog('哈士奇')
dog.bark()

14.8.3 多继承中的重写

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

Python基础6——面向对象

14.9 新式类写法,object类

# 写法一
class A:
    pass
# 写法二
class A():
    pass
# 写法三,推荐
class A(object):
    pass

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

14.10 多态

14.10.1 多态基础

python中的多态是一个伪多态

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

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

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

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


# + 同样的+号,不同的对象使用,就会有不同的结果
print(10+10)
print("10"+"10")
class Animal(object):
    def walk(self):
        print("动物在走路")

class Cat(Animal):
    def walk(self):
        print("走猫步")
miao = Cat()
miao.walk() 
# 输出结果
# 走猫步

class People(Animal):
    def walk(self):
        print("两条腿走路")
people = People()
people.walk()
# 输出结果
# 两条腿走路

14.10.2 多态性

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

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

class A(object): #父类
    def speak(self):
        print("群众的眼睛是雪亮的")

class C1(A):  #子类1
    def speak(self):
        print("年轻人不讲武德")

class C2(A):  #子类2
    def speak(self):
        print("心疼giegie")

def test(obj): #定义一个函数,把对象作为参数传入
    obj.speak()

c1 = C1()
# c1.speak()
test(c1)  
# 输出结果
# 年轻人不讲武德

c2 = C2()
# c2.speak()
test(c2)
# 输出结果
# 心疼giegie

14.11 类方法和静态方法

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

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

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

14.11.1 静态方法

使用@staticmethod符号进行定义

class 类名:
    @staticmethod  #定义为静态方法
    def 方法名(形参):
        方法体
# 调用格式
类名.方法名(参数)
对象名.方法名(参数)

class Dog(object):

    @staticmethod #静态方法:类中的函数。可以用类名调用类属性,但是不推荐。
    def run():
        print("狗狗在跑步")

Dog.run()

14.11.2 类方法

使用@classmethod符号进行定义

针对类对象定义的方法

class 类名
    @classmethod #类方法
    def 方法名(cls): #出现cls参数
        方法体
class Cat(object):   
    name = '布偶'  #类属性

    @classmethod  #类方法
    def sleep(cls): #这里的cls是指Cat这个类
        print(cls)
        print("猫猫在睡觉")

print(Cat)
Cat.sleep()
# 输出结果
# <class '__main__.Cat'>
# <class '__main__.Cat'>
# 猫猫在睡觉

14.12 魔法方法

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

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

14.12.1 __doc__方法


class A:
    '''  
    这是类的描述信息
    '''
    # 必须要使用'''来表示
    pass

print(A.__doc__)

# 这是类的描述信息

14.12.2 __str__方法

# 如果类中定义了__str__方法,那么在打印实例化对象,默认输出该方法的返回值

# str方法必须返回一个字符串
class A:
    def __str__(self):
        return "类似于java的toString方法"
a = A()
print(a)

14.12.3 __module__ 、__class__ 方法

pytest.py 
class C:
    def funa(self):
        print("这是C类的实例方法")


main.py
import pytest
pt = pytest.C()
print(pt)
pt.funa()

print(pt.__module__) #输出结果: pytest 所在模块
print(pt.__class__)  #<class 'pytest.C'>

14.12.4 __eq__

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

14.12.4 __hash__

点赞
收藏
评论区
推荐文章
从一个 10 年程序员的角度告诉你:搞懂 Java 面向对象有多容易?
前言:1)java面向对象语言,面向过程围绕过程(解决问题步骤),面向对象围绕实体(名词,特性(属性),行为(动作、方法))。它们设计思想区别在于关心核心不同的。主流都是面向对象的。实际开发,先按面向对象思想进行设计,具体实现时面向过程(人习惯)2)java怎么支持面向对象呢?a.万物皆对象,所有的类都是Object子类b.java中支
菜园前端 菜园前端
1年前
什么是面向对象编程?
原文链接:什么是面向对象编程?面向对象程序设计(ObjectOrientedProgramming,OOP)是一种计算机编程架构,也可以理解为是一种编程的思想。面向对象程序设计的核心就是对象和类,对象也是类的实例化,类是对现实对象的抽象。对象间通过消息传递
Wesley13 Wesley13
3年前
java面试考点解析(4):面向对象思想、系统架构设计
\ 一、面向对象思想 \1、面向对象的特征有哪些方面?答:面向对象的特征主要有以下几个方面:\抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象
Bill78 Bill78
3年前
Python入门之类(class)
Python3面向对象Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对
Bill78 Bill78
3年前
Python入门之类(class)
Python3面向对象Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对
Wesley13 Wesley13
3年前
java
2、面向对象(封装)面向对象思想:面向对象是基于面向过程的编程思想。面向过程:强调每一个功能的步骤面向对象:强调的是对象,然后用对象去调用功能特点A:符合我们思考习惯的思想
Stella981 Stella981
3年前
Python面向对象编程
本知识点参考廖雪峰的Python课程\https://www.liaoxuefeng.com(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.liaoxuefeng.com)\
Wesley13 Wesley13
3年前
JAVA类和对象创建
!(https://oscimg.oschina.net/oscnet/22ac82441e269125878e950d13f2825b44f.jpg)  面向对象  学习目标:  理解面向对象的编程思想  理解类与对象的关系  如何创建类与对象  方法重载  一:什么是面向对象编程(OOP)  面向对象编程(Object
Wesley13 Wesley13
3年前
JAVA面向对象
一、java面向对象的特征?答:java面向对象的特征:封装、继承、多态、抽象。如果问java面向对象的三大特征是什么?那就是封装、继承、多态,但说到面向对象,还有一个很主要的特征就是抽象。1、封装a)铺垫:Java把真实世界中某些具有共同特征的实体抽象成Java中的类,类的实例就是一个对象,而对象和真实世界的实体是一一