聪哥哥教你学Python之面向对象编程

什么是面向对象编程?

引用百度百科解释:

面向对象程序设计(Object Oriented Programming)作为一种新方法,其本质是以建立模型体现出来的抽象思维过程和面向对象的方法。模型是用来反映现实世界中事物特征的。任何一个模型都不可能反映客观事物的一切具体特征,只能对事物特征和变化规律的一种抽象,且在它所涉及的范围内更普遍、更集中、更深刻地描述客体的特征。通过建立模型而达到的抽象是人们对客体认识的深化。

既然说到面向对象,也就不能不提面向过程。

那么是什么是面向过程呢?

面向过程”(Procedure Oriented)是一种以过程为中心的编程思想。“面向过程”也可称之为“面向记录”编程思想,他们不支持丰富的“面向对象”特性(比如继承、多态),并且它们不允许混合持久化状态和域逻辑。就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。

或许还会有人问,面向过程和面向对象的区别是什么?

这个聪哥哥我也不知道,所以参考一位博友朋友所说的:

面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了;

面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

可以拿生活中的实例来理解面向过程与面向对象,例如五子棋,面向过程的设计思路就是首先分析问题的步骤:

1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。把上面每个步骤用不同的方法来实现。

如果是面向对象的设计思想来解决问题。面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为:

1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。

可以明显地看出,面向对象是以功能来划分问题,而不是步骤。同样是绘制棋局,这样的行为在面向过程的设计中分散在了多个步骤中,很可能出现不同的绘制版本,因为通常设计人员会考虑到实际情况进行各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。

面向对象和面向过程编程的优缺点是什么?

面向过程
  优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源,比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。 
  缺点:没有面向对象易维护、易复用、易扩展

面向对象
  优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护 
  缺点:性能比面向过程低

今天聪哥哥我主要讲的是类和实例、访问限制、继承和多态、获取对象信息、实例属性和类属性等五个方面。

有一定编程语言基础的朋友们,可以联系到自身经常用到的编程语言,通过对比进行学习,同时也可以温习。

一、类和实例

面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。

示例一:

# -*- coding: utf-8 -*-

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def get_grade(self):
        if self.score >= 90:
            return 'A'
        elif self.score >= 60:
            return 'B'
        else:
            return 'C'

lisa = Student("Lisa",100)
bart = Student("Bart",50)
print(lisa.name,lisa.get_grade())
print(bart.name,bart.get_grade())

聪哥哥有话说:

(1)类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响;

(2)方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;

(3)通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。

二、访问限制

在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。

示例一(如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问,所以,我们把Student类改一改):

# -*- coding: utf-8 -*-

class Student(object):

    def __init__(self, name, score):
        self.__name = name
        self.__score = score

    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))

bart = Student("聪哥哥",100)
print(bart.__name)

改完后,对于外部代码来说,没什么变动,但是已经无法从外部访问实例变量.__name实例变量.__score

结果如图:

三、继承和多态

在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。

继承的好处是不言而喻的,继承是为了复用,复用是为了降低代码冗余。

来一段示例说明,比如动物类继承示例

示例一:

# -*- coding: utf-8 -*-

class Animal(object):
    def run(self):
        print('Animal is running...')
		
class Dog(Animal):

    def run(self):
        print('Dog is running...')

    def eat(self):
        print('Eating meat...')

class Cat(Animal):
    pass
	
dog = Dog()
dog.run()
dog.eat()

cat = Cat()
cat.run()

聪哥哥有话说:

继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。

四、获取对象信息

当我们拿到一个对象的引用时,如何知道这个对象是什么类型、有哪些方法呢?

基本类型都可以用type()来判断,例如:

# -*- coding: utf-8 -*-
print(type(1234))

如图:

继承关系可以使用isinstance()

例如:

# -*- coding: utf-8 -*-

class Animal(object):
    def run(self):
        print('Animal is running...')
		
class Dog(Animal):

    def run(self):
        print('Dog is running...')

    def eat(self):
        print('Eating meat...')

class Cat(Animal):
    pass
	
dog = Dog()
cat = Cat()
print(isinstance(cat,Cat))


结果如:

如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:

# -*- coding: utf-8 -*-
print(dir("ABC"))

结果如图:

聪哥哥有话说:

通过内置的一系列函数,我们可以对任意一个Python对象进行剖析,拿到其内部的数据。要注意的是,只有在不知道对象信息的时候,我们才会去获取对象信息。

五、实例属性和类属性

由于Python是动态语言,根据类创建的实例可以任意绑定属性。

或许有哪位小哥哥或是小姐姐会问什么是动态语言,然后接着又会问,有动态语言,就有与之相反的静态语言,那么什么是静态语言。

最后产生的问题就是什么是动态语言?什么是静态语言?动态语言和静态语言的区别?动态语言和静态语言的优劣?

问题一个一个来回答。

问:什么是动态语言?

答:引用百度百科:动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化,类型的检查是在运行时做的,优点为方便阅读,清晰明了,缺点为不方便调试。

问:什么是静态语言?

答:静态语言是在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型。

或许有人说,我听不懂这么官方的说辞。

那好,接下来由聪哥哥来通俗解答:动态语言不需要编译即可运行,而静态语言需要编译后才能运行(关于动态语言和静态语言的区别,这个也是答案)。

问:动态语言和静态语言的优劣比较?

答:

静态语言的优势:

(1)由于类型的强制声明,使得IDE有很强的代码感知能力,故,在实现复杂的业务逻辑、开发大型商业系统、以及那些生命周期很长的应用中,依托IDE对系统的开发很有保障;

(2)由于静态语言相对比较封闭,使得第三方开发包对代码的侵害性可以降到最低;

(3)代码运行速度快。

静态语言的劣势:

代码不够简洁。

动态语言的优势:

(1)思维不受束缚,可以任意发挥,把更多的精力放在产品本身上;

(2)集中思考业务逻辑实现,思考过程即实现过程。

动态语言的劣势:

不方便调试,命名容易混淆。

代码示例:

# -*- coding: utf-8 -*-
class Student(object):
     name = '聪哥哥'
	 
s = Student() #实例
print(s.name)

聪哥哥有话说:

(1)实例属性属于各个实例所有,互不干扰;

(2)类属性属于类所有,所有实例共享一个属性;

(3)不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误。

小结:

聪哥哥有话说,对于本章学习,有一定的编程经验人士学习起来,特别是接触过面向对象这个概念,或者是有Java的开发经验,很容易学习。

猜你喜欢

转载自blog.csdn.net/JavaAndchief/article/details/83715788