Python面向对象编程及三大特征(封装,继承,多态)实例简析

0,什么是 “ 面向对象编程 ” ?

1,面向对象的基础实例

2,什么是封装?Python的封装有哪三种形式?

3,Python中的继承

4,Python中的多态

零   什么是 “ 面向对象编程 ” ?

面向对象(Object Oriented)是软件开发方法。面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统网络管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。

                                                                                                                                                                           ————百度百科

 简单地说,就是将现实世界中的元素加以修饰,存放到计算机上进行运算和处理的一种特殊的编程思路

此所谓面向对象编程

面向对象是一个非常非常复杂繁琐抽象的概念,一句两句甚至是10篇博客都不能讲清楚,所以在这里我要简述的仅仅是Python中面向对象编程的基本概念

 

Python3面向对象

Python诞生于1989年底的那个圣诞节;Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。在所有的面向对象编程语言中(C++,Python,PHP,Java 等等...),面向对象这一技术所拥有的基本单位都是大同小异,所以只要熟练掌握了其中一种编程语言,简单的了解一下其他语言的语法也可以快速掌握。

 

面向对象技术简介

所有的面向对象编程语言都有三大特征:

  • 封装

  • 继承

  • 多态   

其中,Python天生支持多态

在面向对象的语言中都会拥有以下的特有名词:

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 方法:类中定义的函数。
  • 类变量:又叫属性,类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。(在Python中没有方法的重载,只有重写)
  • 局部变量:局部属性,定义在方法中的变量,只作用于当前实例的类。
  • 实例变量:又叫实例属性,在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
  • 实例化:创建一个类的实例,类的具体对象。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

和其它编程语言相比,Python 在尽可能不增加新的语法和语义的情况下加入了类机制。

Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类(多继承),派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。

Python是一门弱类型语言,对象可以包含任意数量和类型的数据。

下面通过一个最基础的Python程序解释一下什么是面向对象的程序设计:

壹  面向对象的基础实例

上代码


"""
在python中,定义类使用关键字是class
python的中类名称定义规则和其他编程语言一致,遵循的是大驼峰,但我们建议依然使用下划线命名法
"""
# class User:
# 这两种写法在python3一致,上面的写法其实就是下面的写法
# 也就是python默认定义的任何类都是object类的子类
# class User:  <===>  class User(object):

class User(object):   #创建一个类 ‘ User ’

    # 重写方法 __init__
    # self 这个参数必须存在
    def __init__(self,username,age,gender,email,tel):  # init 初始化函数中,定义类属性

        self.username = username    #每一行相当于将定义的类属性值赋给了self.xxxx全局类属性
        self.age = age
        self.gender = gender
        self.email = email
        self.tel = tel


u = User("Alexz","20","male","[email protected]","136xxxxx118")   # 构建对象,也叫作实例化一个对象,同时向内传参,类似于函数传参
print(u.username)   #调用属性,直接输出
print(u.age)
print(u.email)
print(u.tel,"\n\n")

u.username = "新垣結衣  あらがき ゆい"  # 调用属性,修改对象的属性值
u.age = "32"
u.email = "[email protected]"
u.tel = "我也不知道"
print(u.username)   #输出修改之后的内容
print(u.age)
print(u.email)
print(u.tel)

输出:

"D:\Python project\venv\Scripts\python.exe" "C:/Users/95385/Documents/Tencent Files/953852521/FileRecv/day10_code/day10/面向对象.py"
Alexz
20
[email protected]
136xxxxx118 


新垣結衣  あらがき ゆい
32
[email protected]
我也不知道

进程已结束,退出代码 0

具体的内容我认为注释已经说的很清楚了,这就是一个最简单的Python面向对象的程序实例

贰   什么是封装?Python的封装的三种形式

封装,封装的是Python某个类中的类属性,即全局变量,就是上个例子中的这个:封装的含义就是将这些个变量变成外界不能直接调用和修改的 “ 不可变的稳定属性 ”

 

我们为什么要用封装呢?

为什么要用封装,封装简单的说能屏蔽方法的复杂性,比如只要知道方法的参数类型就可以使用方法,再说降低模块之间的耦合性,就是模块之间的联系,让之相互独立,能提高系统的健壮性,就是不容易崩溃;比方说有一个极其复杂而且属性方法非常多程序,现在需要向其传入一个稳定(不改变的)参数,比如新实例化了一个类之后,给他的类.ID就是不易改变的全局变量(类属性),这样我们在调用传参的时候就能很容易将传入参数隐藏,是整个程序更加健壮,更加稳定易读。

我们需要封装的话首先要将类属性的命名名称前加上双下划线:__   而后给予的赋值就是类变量

封装有哪三种形式?

"""
这是一个基础的类

"""
class Admin(object):

    def __init__(self, username, nickname, type, email):
        # 封装属性,私有化属性
        self.__username = username
        self.__nickname = nickname
        self.__type = type
        self.__email = email


    def get_username(self):                
        return self.__username
"""通过这个方法,可以在函数外部调用他,从而达到获取到封装属性的值,该函数就相当于当做中介,将被封装属性的值传递了出去
"""

    def set_username(self, username):
        self.__username = username
"""通过在外不调用这个方法,可以把外部需要的参数传入这个方法,然后方法相当于中介再将参数转而赋值给被封装的属性;通过这个方法,才能将外部参数赋给内部的私有属性
"""

    def get_nickname(self):
        return self.__nickname

    def set_nickname(self, nickname):
        self.__nickname = nickname

方式一:通过调用类中的内置方法获取到封装属性的值或通过内置方法重新设置封装属性的值

if __name__ == '__main__':
    # 实例化Admin的对象
    admin = Admin("admin", "超级管理员", 3, "[email protected]")

    print(admin.get_username())  #通过调用内置方法输出被封装属性的值
    admin.set_username("alexz")  #通过调用内置方法修改被封装属性的值
    print(admin.get_username())   #再次输出查看结果

结果:

方式二:在类中调用 property 全局函数,传入内置写好的获取或修改被封装属性的方法名称,就可以在主函数中直接调用,而不必调用传递值的内置方法

即在主函数中添加如下这一行代码:

    nickname = property(get_nickname, set_nickname)

于是我们在外部调用输出或修改属性的时候,把它视为普通属性那样去对待即可:

if __name__ == '__main__':
    # 实例化Admin的对象
    admin = Admin("admin", "超级管理员", 3, "[email protected]")

    print(admin.nickname)
    admin.nickname = "永久管理员"
    print(admin.nickname)

结果如下:

方式三:使用@property装饰器,完成封装

在类的末尾加上@property修饰器

if __name__ == '__main__':
    # 实例化Admin的对象
    admin = Admin("admin", "超级管理员", 3, "[email protected]")

    print("--封装的第三种写法,使用@property装饰器,完成封装---")
    print(admin.type)
    admin.type = 123
    print(admin.type)

最后调用输出的时候只需要想普通属性那样去使用就好了

叁   Python中的继承

灵魂三问:什么是继承?为什么要继承?如何用继承?

  • 继承是一种创建新的类的方式,新创建的叫子类(派生类),继承的叫父类(超类、基类)。
  • 特点:子类可以使用父类的属性(特征、技能)
  • 继承是类与类之间的关系
  • 继承的作用是减少代码冗余、提高重用性
class animal(object):
    def __init__(self,food,leg,weight):
        self.food = food
        self.leg = leg
        self.weight = weight
    def say(self):
        print("i am very happy !")

class virtue(object):
    def println(self):
        print("food is",self.food)
        print("it has",self.leg,"legs")
        print("it weight is",self.weight)


class bull(animal):
    pass

class pig(animal,virtue):
    pass

if __name__ == '__main__':
    bulls = bull("grass","4","300KG")
    pigs = pig("Leftovers","5","200KG")

    bulls.say()
    pigs.say()
    pigs.println()

这里面定义了两个基类:animal和virtue,然后用两个派生类pig和bull去分别继承,其中派生类pig继承了两个基类,也就是说在Python中是可以多继承的

最后在主函数中调用的结果:

肆   Python中的多态

  • 让具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容(功能)的函数。
  • 只关心对象的实例方法是否同名,不关心对象所属的类型;
  • 对象所属的类之间,继承关系可有可无;
  • 多态的好处可以增加代码的外部调用灵活度,让代码更加通用,兼容性比较强;
  • 多态是调用方法的技巧,不会影响到类的内部设计。

我们还是用上面的哪个基类,但是我们的pig今天心情很 “ 糗 ” ,所以它在说 “ i am happy ” 不太合适了,所以我们可以再定义派生类的时候,进行一些 “ 重写 ” :

class pig(animal,virtue):
    def say(self):
        print("他妈的今天真是糟糕透顶,一只母猪都没遇见!")
    pass

于是我们在主函数中调用输出的时候,便会是这种结果:

这是因为所派生的方法,在派生类中被重写了一遍,相当于重写定义,将她所说的话改变了

这也是,同一个基类所派生出来的子类,可以拥有多种不同的函数功能(形态),也就是我们所说的多态。

负壹   面向对象思想小结

多态的存在可以说是将面向对象这个编程思想应用发挥到了极致

本身面向对象就是在模拟自然界中所存在的事物,继承这个思想就是将派生类之间的共同点所表示出来:比方说人都有两个眼睛,两个耳朵,一个脑袋,这些事恒古不变的规律,通过继承他们的父类的各个方法和属性,便可以在定义的时候将他们的功能点一概而论,省去了大把的代码来阐述一件事物;而多态的存在就是将他们的不同点描绘出来:比如我比吴彦祖长得高,那我再创造我这个子类的时候将身高就需要重写一下,吴彦祖比我帅;创造吴彦祖的时候就要将吴彦祖五官的方法就要修饰精致一些.......

而后就是封装这个编程思想,封装的存在可以说是我们这种搞渗透的 “ 克星,因为封装一来是封装了复杂度,二来是保护了隐私性,就相当于将传入的数据进行二次加工,可以滤除特殊字符串啊,添加白名单等等,对外显示的接口我们可以修饰成原本的模样(方法二和方法三),这样就在源码的基础上最大限度的增加了程序的健壮性,以及数据的安全性,隐私性等等

之前我在这一篇博客(https://blog.csdn.net/Alexz__/article/details/104488102)开头所举的那个例子:食堂做饭的例子

什么是面向过程?

打个比方,食堂要给1000个员工做饭,面向过程的话就是:给员工A做西红柿炒蛋,给员工A做青椒小炒肉,给员工B做西红柿炒蛋,给员工B做青椒小炒肉,给员工C做西红柿炒蛋,给员工C做青椒小炒肉,给员工D......  以此类推,由上而下,总头至尾按部就班的执行所需要的步骤,就是面向过程的编程。

这里我要完善一下:什么是面向对象?

食堂要给1000个员工做饭,面向对象的话就是:先做好慢慢一大锅西红柿炒蛋,满满一大锅青椒小炒肉,然后员工A来了,乘上两个菜;员工B来了,乘上两个菜,员工C来了.....

这就是面向对象

花花世界迷人眼,没有实力别赛脸。

                                                                 ————你地寒王

发布了46 篇原创文章 · 获赞 47 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Alexz__/article/details/104599832
今日推荐