Python学习(八):类和对象 以另一种思维看待世界

第8 章 类和对象 以另一种思维看待世界

对世界万物的状态与行为进行归纳与分类,以此分析个体与个体间的相互作用与影响方法。

Table of Contents

  • 前言
  • 审视问题域的视角
  • 你是不是人
  • 类和对象
  • code
  • 数据封装

前言

在刚学 java的时候,老师就开始灌输 everythingisobject(万物皆对象)的思想,

一切事物皆对象,通过面向对象的方式,将现实世界的事物抽象成对象,现实世界中的关系抽象成类、继承,帮助人们实现对现实世界的抽象与数字建模。

面向对象的分析根据抽象关键的问题域来分解系统。面向对象的设计是一种提供符号设计系统的面向对象的实现过程,它用非常接近实际领域术语的方法把系统构造成“现实世界”的对象。

审视问题域的视角

在现实世界中存在的客体是问题域中的主角,所谓客体是指客观存在的对象实体和主观抽象的概念,他是人类观察问题和解决问题的主要目标。

在一个熟悉的环境中,例如大家应该对学校都很熟悉,对于一个学校来说,无论学校大小,学生和老师都是主要的成员,也可以说是主要的客体,每个客体都有一些属性和行为,学生有学号、姓名、性别等属性,以及上课、考试、做实验等行为。因此,每个个体都可以用属性和行为来描述。

你是不是人

记得上学的时候,好像是思想品德或者政治之类的哲学课。提到 你是不是人,当时问的一个同学,那个同学回答说:‘我是人’, 老师呵斥 你不是人,当然这并不是和这个同学有仇,也不是这个同学做了什么。这里的 在哲学上病不是一个,也就是 你永远不可能是人是我们每个特殊个体高度归纳,而我们每个都是一个 特殊的个体,而不是抽象的 是我们的 共性,我们每个个体又有自己的 特性,所以 人非人(具体哲学意义,去问我老师吧)

抽象是人类解决问题的基本法宝。良好的抽象策略可以控制问题的复杂程度,增强系统的通用性和可扩展性。将描述客体的属性和行为绑定在一起,实现统一的抽象,从而达到对现实世界客体的真正模拟。

现实生活中,我们经常讲一类有共性的事物,进行分类,例如:桌子,椅子,汽车,动物等

类和对象

具有相同特性和行为的事物的抽象就是类。例如上面提到的 表示了一类相同特性的个体,每个个体又叫做 对象,人就是我们的高度归纳和抽象,我们就是人的具体化,同理 对象的抽象是 的具体化就是 对象,也可以说 的实例是 对象

类具有属性,它是对象的状态的抽象。 类具有操作,它是对象的行为的抽象。

code

以人为例,在Python中,定义类是通过class关键字:

class Person(object):
    pass

class后面紧接着是 类名,即 Person,类名通常是大写开头的单词,紧接着是 (object),表示该类是从哪个类 继承下来的,继承的概念我们后面再讲,通常,如果没有合适的继承类,就使用 object类,这是所有类最终都会继承的类。毕竟我们都是 共产主义接班人

定义好了 Person类,就可以根据 Person类创建出 Person的实例,创建实例是通过 类名+ ()实现的:

class Person(object):
    pass
zhangyunan = Person()
zhangyunan
Out[4]: <__main__.Person at 0x10fa44940>

可以看到,变量 zhangyunan指向的就是一个 Person的实例,后面的0x10fa44940是内存地址,每个object的地址都不一样,这就是特性了,而 Person本身则是一个类。也是就我们的共性。

我怎么体现我的特性,首先我的有个名字

python可以自由地给一个实例变量绑定属性,比如,我要有个名字:

zhangyunan.name = '张瑀楠'
zhangyunan.name
Out[6]: '张瑀楠'

现在社会平等了,每个人都可以有自己的名字和性别,当然这是必须的,由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的 __init__方法,在创建实例的时候,就把name,sex等属性绑上去:

class Person(object):

    def __init__(self, name, sex):
        self.name = name
        self.sex = sex

注意:特殊方法_init_前后有两个下划线!!!

注意到 __init__方法的第一个参数永远是 self,表示创建的实例本身,因此,在 __init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。

有了 __init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与 __init__方法匹配的参数(还记得位置参数吧)但self不需要传,Python解释器自己会把实例变量传进去:

class Person(object):

    def __init__(self, name, sex):
        self.name = name
        self.sex = sex


zhangyunan = Person('张瑀楠', 'male')

和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。

数据封装

面向对象编程的一个重要特点就是数据封装。在上面的 Person类中,每个实例就拥有各自的name和sex这些数据。我们可以通过函数来访问这些数据,比如访问名字

print(zhangyunan.name)

张瑀楠

我想知道自己的名字,没有必要让别人告诉我吧!

但是,既然Person实例本身就拥有这些数据,要访问这些数据,就没有必要从外面的函数去访问,可以直接在Person类的内部定义访问数据的函数,这样,就把“数据”给封装起来了。这些封装数据的函数是和Student类本身是关联起来的,我们称之为类的方法:

class Person(object):
    """
    人类,每个人都应该有名字和性别
    """

    def __init__(self, name, sex):
        self.name = name
        self.sex = sex

    def print_name(self):
        """
        打印我的名字
        :return: 
        """
        print('我的名字是:', self.name)


zhangyunan = Person('张瑀楠', 'male')

zhangyunan.print_name()

我的名字是: 张瑀楠

要定义一个方法,除了第一个参数是self外,其他和普通函数一样。要调用一个方法,只需要在实例变量上直接调用,除了self不用传递,其他参数正常传入:

还记得讲函数时用到的的学生等级函数吧

def score_level(score):
    if score < 60:
        level = '不及格'
    elif score < 70:
        level = '继续努力'
    elif score < 80:
        level = '中等'
    elif score < 90:
        level = '良好'
    else:
        level = '优等生'
    return level

这方法是不是和学生有关呢?那赶紧趁热来个学生类吧!

class Student(object):
    """
    学生类,主要就是学习和切磋成绩了,除了姓名和性别,他们的分数是最重要的
    """
    def __init__(self, name, sex, score):
        self.name = name
        self.sex = sex
        self.score = score

    def score_level(self):
        """
        告诉大家,我的学习成绩
        :return:
        """
        if self.score < 60:
            level = '没你考的好'     # 都不及格了,就含蓄一点了
        elif self.score < 70:
            level = '开心就好'
        elif self.score < 80:
            level = '继续努力'
        elif self.score < 90:
            level = '自信满满'
        else:
            level = '还有谁'
        return level


# 也不知道为什么,100分的试卷,我老是考101 分,别人都不信
zhangyunan = Student('张瑀楠', 'male', 101)

print(zhangyunan.score_level())

还有谁

原文发布于微信公众号 - 全栈布道士(gh_773193545262)

原文发表时间:2017-11-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏NetCore

驳“反驳老赵之“伪”递归”

晚上看到鹤冲天的“反驳老赵之“伪”递归”,大概看了一下,主要是反驳老赵提出的“伪”递归的概念,特别是“伪”,看起来说的都很有道理,但我个人认为,老赵说的没有错,...

2285
来自专栏大史住在大前端

野生前端的数据结构练习(9)冒泡排序,选择排序,插入排序

bubble sort的是最基本的算法,被誉为永远会被考从来不被用的算法,基本原则是大数右移,每轮遍历后最右侧的数是最大的,所以下一轮循环时可不予考虑,时间复杂...

792
来自专栏学习力

《Java从入门到放弃》JavaSE入门篇:运算符

1646
来自专栏猿人谷

O(n)时间的排序

题目:某公司有几万名员工,请完成一个时间复杂度为O(n)的算法对该公司员工的年龄作排序,可使用O(1)的辅助空间。      题目特别强调是对一个公司的员工的年...

2148
来自专栏个人随笔

Java 关于接口的那点事儿

接口的应用 接口是一种能力 关键字:interface 语法:  public interface MyInterface{   public void ...

3978
来自专栏C语言C++游戏编程

C语言内置运算符丰富到令人头皮发麻,C语言基础教程之运算符篇

运算符是告诉编译器执行特定数学或逻辑函数的符号。C语言内置运算符丰富,并提供以下类型的运算符 -

1291
来自专栏趣谈编程

选择排序

面试官: 聊聊选择排序 选择排序是一种简单直观的算法,今天我们聊聊选择排序的思想,代码以及复杂度 排序思想 一天,小一尘和师傅下山去了,在集市中路经一个水果摊,...

3338
来自专栏coding for love

JS进阶系列

在JS入门难点解析系列中,我们对JS的一些重要概念,比如:作用域,作用域链,原型,原型链,继承,活动对象,this,执行环境,变量声明,函数声明等进行了详细的分...

821
来自专栏java一日一条

5 分钟搞定 Java Comparable 接口

我们应该如何对事物进行比较和排序?这问题听上去有点莫名其妙,但我希望你认真考虑一下。比方说,我们有一组苹果:

541
来自专栏Java后端技术栈

Java提供的排序算法是怎么实现的?快排?

前几天整理的一套面试题,其中有一个问题就是Java的JDK中我们见到的Collections.sort()和Arrays.sort()这两个排序算法的实现方式是...

1533

扫码关注云+社区

领取腾讯云代金券