python入门《基础知识8--类和对象》

本文将总结自己对Python中类和对象的理解

写在开头:

类的定义与创建参考了:https://blog.csdn.net/qq_26442553/article/details/81744890

slef的理解部分参考了:https://blog.csdn.net/xrinosvip/article/details/89647884

目录

一、面向对象

二、类的定义与创建

三、类的方法

PS:python中函数名中下划线的含义:https://blog.csdn.net/u010098331/article/details/52054019

四、类的特殊方法

五、类的关系

六、类的继承


一、面向对象

首先,面向对象是一种编程思想,是一种编程模式,之前学习c语言,c语言是面向数据,或者专业化一点叫做“结构化编程”甚至是“函数式编程”,这并非是否定结构化编程,但就目前来看,结构化编程在编写一些小脚本或者自娱自乐足够,对于信息化告诉发展的当今世界却是远远不够的。而面向对象提倡在构建软件系统时使用贴近真实生活的思维方式进行设计和编程,这既降低了编程人员的思维难度,又便于维护修改。在面向对象思想中,一切都是对象,每个对象都有它的属性和方法,每个对象都可以通过消息互相交互,在这一点上,python几乎可以说是面向对象思想语言的典型范例。

面向对象思想中几个关键术语:类,对象,继承,多态。

二、类的定义与创建

类由属性和方法组成。在python中,使用class 来定义类。

1.在python中定义类会有新式与旧式之分:

  • 新式类:以 object 为基类的类,推荐使用
  • 经典类:不以 object 为基类的类,不推荐使用
  • 在 Python 3.x 中定义类时,如果没有指定父类,会 默认使用 object 作为该类的 基类 —— Python 3.x 中定义的类都是 新式类
  • 在 Python 2.x 中定义类时,如果没有指定父类,则不会以 object 作为 基类
  • 新式类 和 经典类 在多继承时 —— 会影响到方法的搜索顺序
  • 为了保证编写的代码能够同时在 Python 2.x 和 Python 3.x 运行!
  • 今后在定义类时,如果没有父类,建议统一继承自 object
class 类名(object):    
    pass
 
#尽量不要用下面这种老式写法,虽然不会报错,但是不推荐
class 类名:    
    pass

2.类属性定义有显式定义和隐式定义两种

  • 显式定义:类属性在class下面直接定义
  • 隐式定义:类属性在方法里面隐式定义。(需使用self)
  • PS:类方法的定义中第一个参数必须为默认的self
#显式定义
class TestA(object):
    value = 0
    def printf(self):
        print(value)
#隐式定义
class TestB(object):
    def printf(self):
        self.value = 0
        print(self.value)

PS:介绍下python中的self:self表示自身,一般用在类中,在实例化时表示当前对象本身,在类中定义方法第一个参数必须是self(python规定的语法),python类/对象中调用自身属性或者自身方法必须通过self.调用。

  • self是实例/对象的属性的集合
  • 可以把 self 理解成存储 实例化对象属性的字典(dict), self 存储属性,而没有动作执行
  • self总是指调用时的类的实例。

更多详情可参见https://blog.csdn.net/xrinosvip/article/details/89647884

1.创建类,类主要由类名,属性,方法组成,当然创建一个类时,属性和方法可以选择的。
class Person:
    def cry(self):  #类方法:跟函数的定义类似,但是self参数自带的,这也是类的方法和普通方法的区别。
        print("I can cry")
    def speak(self):
        print("I can speak:%s"%(self.word))
 
---------创建对象-----------------------------------------------------------------------
tom =Person()  #创建对象,直接类名(),不用像java中还要new,所以python更加简洁
tom.cry()     #调用对象的方法
tom.word="hahah"
tom.speak()
tom.age =18  #给对象添加属性 ,属性不用在类定义时声明,但这种方法给对象赋值麻烦,每个对象都要赋值。
tom.age =19  #上面已经给tom添加过age属性,再次属于调用,重新赋值。
 
----------执行结果-------------------------------------------------------------------------
'''
I can cry
I can speak:hahah
'''
 
2.给类初始化属性,在对象创建时就给对象设定了一些默认值。这样不用给每个对象都添加属性了,比如每个Person都是china,sex都是male.
 _init_(self)该类的方法有点类似java中类的构造器,可以给类的对象赋初始值。
------------------------------------------------------------------------------------------
class Person1:
    def __init__(self):  #_init_(self),主要给类初始化一些属性,对象创建时自动调用该方法执行
        self.country ="china"
        self.sex = "male"
 
    def speak(self):
        print("I am  from %s  ,wuwuwuwuu"%self.country)
-------------创建对象----------------------------------------------------------------------
jack = Person1()
jack.speak()
print(jack.country,jack.sex)
 
tom=Person1()
tom.speak()
print(tom.country,tom.sex)
--------------执行结果如下:----------------------------------------------------------------
'''
I am  from china  ,wuwuwuwuu
china male
I am  from china  ,wuwuwuwuu
china male
'''
 
3.属性虽然初始化了,但是固定死的,而实际每个对象的属性就不同。
  所以通过初始化时调用参数的形式,给每个对象赋不同的属性值
 
class Person2:
    def __init__(self,name,age): 
        self.age =age   #这种用法类似java中的this.age=age.self意思可以理解为当前对象
        self.name = name #表示将当前对象传进来的参数name的值赋给当前对象的属性name
        self.country = "china" #还是可以给类的每个对象都赋一个默认值。
 
    def speak(self):
        print("name=%s,age=%d"%(self.name,self.age))
-----------创建对象------------------------------------------------------------------------
p1 = Person2("allen",19)
p2 = Person2("sherry",22)
p3 = p2  #让p3=p2.对象的赋值
 
p1.speak()
p2.speak()
 
print("p1:",p1)  #直接打印对象 ,打印的是对象在内存中地址。
print("p2:",p2)
print("p3:",p3) #发现p3的地址跟p2的地址一样。
 
'''执行结果如下:
name=allen,age=19
name=sherry,age=22
p1: <__main__.Person2 object at 0x000001CBA3508BE0>
p2: <__main__.Person2 object at 0x000001CBA3508CF8>
p3: <__main__.Person2 object at 0x000001CBA3508CF8>
'''

三、类的方法

简单的说,类的方法就是在类内部定义的函数,只不过这个函数的首个参数必须是self(代表自身)。类的方法三大原则:

  • 类方法的第一个参数必须是self。
  • 类方法里面调用类本身的属性和方法,都必须在属性和方法前面加self。
  • 类方法的名字开头可以为下划线或者字母,就是私有方法。所谓私有方法就是只能为类的其他方法调用的方法。

python中的私有其实是伪私有,可以通过其他方法访问“私有”函数。

PS:python中函数名中下划线的含义:https://blog.csdn.net/u010098331/article/details/52054019

四、类的特殊方法

python的类方法中,有一部分特殊的方法,它们不同于普通类的方法,主要包括:类的初始化函数和析构函数、类的操作符函数。其实,跟c++差别不大,需要注意的只有:

  • 这类特殊函数名以双下划线开头以双下划线结尾,自定义函数时要避免重名,如__add__,__sub__等
  • 初始化函数叫做__init__相当于C++里头的构造函数,析构函数叫做 __del__,初始化函数在类实例化时会自动调用,析构函数则只有当被调用,将对象从内存在卸载时才会被调用。
  • 与C++中相同,python的操作符函数也是可以重载的

五、类的关系

在面向对象关系中,一般有:继承(泛化)、依赖、关联、聚合、组合等关系,实际上从面向对象思想的角度出发,他们都是用来描述现实某个应用场景下关系关联强度的。

上述几种关系中又可大致分为两类。一类是继承,继承一般是静态的,描述的是程序设计之初就定下来的规则,就好比“男人类”继承自“人类”,“赛车类”继承自“车类”,这种关系是设计之初就定下来的静态规则;第二类是其他,依赖、关联、聚合、组合这些关系与继承不同,是各个类在互相交互之间产生的。例如,在运行过程中,把A作为参数传给B的方法(依赖关系);将A作为B的类属性(关联);将A只作为B的属性,不单独存在也不作为其他类的属性(组合关系)。按照UML的标准,一般将依赖、关联、聚合、组合统称为关联,其中还把依赖成为弱关联,组合成为强关联。

举出具体事例而言,上述概念将更易理解:人和人心是组合关系,人心组成一个整体,人心只作为人的一部分,不单独存在也不构成其他整体,人心与人同时存在同时消亡,是紧紧组合在一起的;又比如车轮和卡车,车轮就是一种聚合关系,车轮是卡车的一部分,但也可以组成其他车,且车轮和卡车也不是同时存在同时消亡的。

  • 依赖:在python中,类A方法的参数是另一个类B,就叫A依赖于B
  • 关联、聚合、组合关系:在python中,如果A的属性中有类B的实例,那么就是关联关系;如果B的实例只作为A的属性存在,那么A和B就是组合关系;如果B的实例海作为其他类的属性存在,A和B 就是聚合关系。

六、类的继承

继承又叫做泛化,是使得一个类获得另一个类所有属性和方法的能力,被继承的类称为父类,继承的类成为子类。

其实类就是将属性和方法捆绑在一起,可以用这个组合为模板实例化一个个对象,就像把轮胎,发动机,钢铁组合起来,起个名字叫汽车,然后按照这个汽车的样式就可以生产一个个小汽车。继承就是在原来这个组合上,加上想添加的组合,比如在普通汽车类上加上“敞篷”类,就成了“敞篷车”,多重继承就是将多个组合混合到一起。

1.单一继承

顾名思义:子类只有一个父类与C++道理相同。python中新式定义类继承自object父类。

python提供super()方法,提供给子类自动寻找父类,避免改动父类时,要一个个更改继承的子类代码。

2.多重继承

一个子类拥有多个父类。

3.重载

  • 如果子类自定义方法和继承父类来的方法名称重合,子类的方法将覆盖父类的方法,这叫做重载。
  • 继承自多个父类的方法相互重名,则继承顺序中从左往右第一个优先级最高,即同是父类,靠左的优先级高。

 

 

发布了37 篇原创文章 · 获赞 1 · 访问量 2743

猜你喜欢

转载自blog.csdn.net/qq_39685968/article/details/97138282