热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

小白学习之路,初识面向对象

一,编程范式所谓编程范式(programmingparadigm),指的是计算机编程的基本风格或典范模式。怎么说呢,每个人都有自己不同的习惯,当然编程也是一样的,每个程序组员根据自

一,编程范式

所谓编程范式(programming paradigm),指的是计算机编程的基本风格或典范模式。怎么说呢,每个人都有自己不同的习惯,当然编程也是一样的,每个程序组员根据自己不同的习惯会写出不同的代码。当然这样肯定是不行的啦,这样的可读性不强,而且太乱了,所以慢慢慢慢的大家就统一编程的风格。编程范式里面呢又包括下面几种(我知道的):面向对象,面向过程,函数式编程。感觉写到这里,需要用一波我自己的土话来跟大家解释一下这三种的大概不同了。

面向对象:在python里面一切皆对象,当然不是你女(男)朋友那个对象。emmm,打个比方吧,假如你高考完了,准备选学校,选专业了,你在想到底是去北大呢,还是去清华呢。你就想可以写个函数,如果选清华有哪些专业,选北大有哪些专业。当然还可以这样写,你可以把清华看成一个对象,北大看成一个对象,然后里面的对象有不同的属性跟方法。你选择了清华,就是实例化了一个清华对象,下一个人选择北大,就实例化一个北大对象。这样看似没得多大区别,但是他能够在里面的属性跟方法添加其他的,可扩展性更强了,而且容易修改,这种思想其实就是面向对象。

面向过程:面向过程就太好理解了。因为我们这种小白,最熟悉的就是面向过程。面向过程呢,就是一步一步实现,然后到最后完成。面向过程就是重要的是过程,但是在使用面向过程时,你想改其中一个地方,你会发现很多地方都要改,一个地方错了,其他地方也错了,所以很麻烦。

函数式编程:其实,我觉得跟面向过程差不多,然后是用函数实现的一种编程方式。

二,面向对象简介

1,认识面向对象

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

2,面向对象特性

面向对象有三大特性:封装,继承,多态

封装:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

继承:继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”。被继承的类称为“基类”、“父类”或“超类”。在这里值得提一下的就是,python支持多继承,之后多继承后面也会提到。通俗来讲,继承就是你继承其他的类,他的属性方法,你都有,而且还可以继续增加或者修改一些属性或者方法。

多态:多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

三,面向对象基础语法

听了这么多的类啊,对象啊,现在就来新建一个类吧。在新建之前,类还分经典类和新式类。

经典类:

技术分享图片技术分享图片
 1 import time
 2 class people:#(class后面的是类名)
 3     #构造函数,在实例化一个对象的时候生成的一些属性写在这里
 4     def __init__(self,name):
 5         self.name=name
 6     def eat(self):
 7         print(%s is eating...%self.name)
 8     def sleep(self,times):
 9         print(%s Is sleeping%self.name)
10         time.sleep(times)
11         print(%s sleep up %self.name)
12 a=people(zzq) #实例化一个对象
13 a.eat() #调用里面的方法
14 a.sleep(1)#调用需要传参的方法
View Code

新式类:(继承了object)

技术分享图片技术分享图片
 1 import time
 2 class people(object):#(class后面的是类名)
 3     #构造函数,在实例化一个对象的时候生成的一些属性写在这里
 4     def __init__(self,name):
 5         self.name=name
 6     def eat(self):
 7         print(%s is eating...%self.name)
 8     def sleep(self,times):
 9         print(%s Is sleeping%self.name)
10         time.sleep(times)
11         print(%s sleep up %self.name)
12 a=people(zzq) #实例化一个对象
13 a.eat() #调用里面的方法
14 a.sleep(1)#调用需要传参的方法
View Code

他们之间的区别在讲了后面的继承跟多继承会讲到,其实在python3中没得区别,一般常用新式类的写法哦。

四,类的继承

面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。

通过继承创建的新类称为子类派生类,被继承的类称为基类父类超类

在python中继承中的一些特点:

  • 1、如果在子类中需要父类的构造方法就需要显示的调用父类的构造方法,或者不重写父类的构造方法。详细说明可查看:python 子类继承父类构造函数说明。
  • 2、在调用基类的方法时,需要加上基类的类名前缀,且需要带上 self 参数变量。区别在于类中调用普通函数时并不需要带上 self 参数
  • 3、Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

1,下面简单介绍一下,继承的一些基本语句

技术分享图片技术分享图片
 1 class Father(object):
 2     def __init__(self,name):
 3         self.name=name
 4     def get_name(self):
 5         print(Father’s name is %s %self.name)
 6     def say(self):
 7         print(Father is say)
 8 class Son(Father):#继承Father类
 9     def __init__(self,name,age):
10         Father.__init__(self,name)#继承父类的构造方法
11         self.age=age
12     def get_name(self):
13         Father.get_name(self)#继承父类的方法
14         print(Son’s name is %s age is %s%(self.name,self.age))
15     def say(self):
16         print(Son is say)#重写say方法
17 a=Son(xxx,18)
18 a.get_name()
19 a.say()
View Code

执行结果:

技术分享图片

在上面的构造方法的继承其实还有一种比较常用的,也是推荐使用的方法,代码如下

1     def __init__(self,name,age):
2         # Father.__init__(self,name)#继承父类的构造方法
3         super(Son, self).__init__(name)#继承父类的构造方法,并且不用知道父类的名字
4         self.age=age

总结一下吧。如果不重构的情况下,默认,子类有父类所有的方法并且跟父类相同。子类还可以继承父类的构造方法或者其他方法,并且在上面添加扩展。如果父类跟子类的方法或者属性重名,那么使用的还是子类的属性或方法。

2,多继承的用法跟分析

在讲到多继承这里大家就要知道在继承的时候需要考虑继承的顺序问题。讲这么多不好理解,我们先看代码,然后在分析吧。

技术分享图片技术分享图片
 1 class F1(object):
 2     def say1(self):
 3         print(this is F1 say1)
 4     def say2(self):
 5         print(this is F1 say2)
 6 class F2(object):
 7     def say1(self):
 8         print(this is F2 say1)
 9     def say2(self):
10         print(this is F2 say2)
11     def say3(self):
12         print(this is F2 say3)
13 class Son(F1,F2):#继承F1,F2两个类
14     pass
15 a=Son()
16 a.say1()
17 a.say2()
18 a.say3()
View Code

执行结果:

1 this is F1 say1
2 this is F1 say2
3 this is F2 say3

通过结果我们可以看到,如果同时继承了两个类,会首先去前面一个类里面找有木有方法或者属性,如果有,就用前面那个类的属性或方法,如果前面没有就用后面的那个类的属性或方法。

讲到这里跟大家讲一下经典类跟新式类的区别吧。但是在讲区别之前,需要带大家了解一下什么叫广度优先跟深度优先。

广度优先:从初始点出发,把所有可能的路径都走一遍,如果里面没有目标位置,则尝试把所有两步能够到的位置都走一遍,看有没有目标位置;如果还不行,则尝试所有三步可以到的位置。这种方法,一定可以找到一条最短路径,但需要记忆的内容实在很多,要量力而行。

深度优先:从初始点出发,不断向前走,如果碰到死路了,就往回走一步,尝试另一条路,直到发现了目标位置。这种不撞南墙不回头的方法,即使成功也不一定找到一条好路,但好处是需要记住的位置比较少。

python2经典类是按照深度优先来继承类的,新式类是按照广度优先来继承类的。

python3经典类和新式类都是统一按照广度优先来继承类的。

当然,有的人还是不能完全理解继承流程,下面是我画的流程图,当然,丑不能怪我!!!

技术分享图片

这个顺序是在继承的时候查找属性和方法的向上查找顺序。

五,类属性,方法扩展

想了一下,属性好像有实例变量,类变量,私有变量等。方法有构造方法,析构函数,私有方法,静态方法,类方法,属性方法等。

1,私有变量,私有方法

私有属性跟私有方法,其实就是只能在类里面能够使用的属性跟方法,外部不能调用使用。

1 class tset(object):
2     def __init__(self,name):
3         self.__name=name   #变为私有属性,只有内部能够调用
4     def __say(self):   #变为私有方法,只有内部能够调用
5         print(self.__name)  #调用私有属性
6     def say(self):
7         self.__say()  #调用私有方法

2,静态方法

普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法。

1 class Test(object):
2     def __init__(self, name):
3         self.name = name
4     @staticmethod  # 把say方法变为静态方法
5     def say():#不能传入其他参数
6         print("hello")
7 d = Test("xxx")
8 d.say()

3,类方法

类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量

1 class Test(object):
2     name=zzq #类变量
3     def __init__(self, age):
4         self.age = age
5     @classmethod  # 把say方法变为类方法
6     def say(self):
7         print("hello %s" %self.name)#只能调用类变量
8 d = Test("xxx")
9 d.say()

4,属性方法

属性方法的作用就是通过@property把一个方法变成一个静态属性

1 class Test(object):
2     def __init__(self, name):
3         self.name = name
4     @property  # 把say方法变为属性方法
5     def say(self):
6         print("hello %s" %self.name)
7 d = Test("xxx")
8 d.say  #相当于say是一个属性,调用的时候相当于调用一个属性,不用加括号

六,类里面的一些特殊方法

1,__str__

1 def __str__(self):#输出对象时,输出的是return的返回值
2     return hahaha

2,__call__

1 def __call__(self, *args, **kwargs):#在调用后面加一个()执行这个方法
2     print(this is call,args,kwargs)
3 Test("xxx")() #在调用的时候后面再加一个括号

3,__doc__,__module__

1 print(Test.__doc__)#打印类的描述
2 print(Test.__module__)#输出类所在哪个模块

4,__class__

print(Test.__class__)#表示当前操作的对象的类是什么

5,__dict__

1 print(Test.__dict__)#打印类中的所有属性,不包括实例化属性
2 a=Test("xxxx")
3 print(a.__dict__)#打印类中所有实例化属性,不包括类属性

6,__del__

1     def __del__(self):#析构函数,在实例化以后自动调用,比如一些关闭数据库连接等操作
2         print(end)

7,__new__

类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__,所以在实例化__init__之前其实先调用了__new__方法的。

 七,反射

相信在写程序的时候都会遇到一个问题就是你想要把字符串转换成需要执行的属性或者类。需要执行对象里的某个方法,或需要调用对象中的某个变量,但是由于种种原因我们无法确定这个方法或变量是否存在,这是我们需要用一个特殊的方法或机制要访问和操作这个未知的方法或变量,这中机制就称之为反射。

简单来讲,反射就是把字符串转化为可以执行的属性或者方法。

技术分享图片技术分享图片
 1 class Dog(object):
 2     def __init__(self,name):
 3         self.name=name
 4     def eat(self):
 5         print(The dog %s is eating... %self.name)
 6 d=Dog("xxx")
 7 chose=input(">>>>")
 8 print(hasattr(d,chose)) #判断输入的chose在d对象中,是否存在属性或者方法
 9 
10 func=getattr(d,chose) #把字符串转化为可以直接使用的属性或者方法
11 func() #如果是方法,调用方法(执行结果:The dog xxx is eating...)
12 print(func) #如果是属性(执行结果:xxx)
13 
14 setattr(d,age,20)#为d增加属性,第二个为属性名,第三个为属性值
15 print(d.age) #执行结果:20
16 def say(self):
17     print(hello,world)
18 setattr(d,talk,say)#把函数say添加到d中,并且函数名为talk
19 d.talk(d) #调用talk方法,因为这是额外添加的方法,需手动传入对象(执行结果:hello,world)
20 
21 delattr(d,name)#删除d中的name属性,delattr不能删除类中的方法
View Code

当然,一般hasattr跟getattr是一起使用的,先用hasattr判断类或对象中是否存在,然后再用getattr获取。getattr不仅仅可以获取对象的方法和属性和方法,还可以获取类的方法和属性。你还可以这样理解,比如d.name在使用getattr的时候可以理解为getattr(obj,str)obj相当于.前面的,str相当于.后面的。

小白学习之路,初识面向对象


推荐阅读
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • vue使用
    关键词: ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
author-avatar
四海承风2502893247
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有