Python面向对象编程_类

Posted 胜天半月子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python面向对象编程_类相关的知识,希望对你有一定的参考价值。

文章目录


其实面向对象是初学Python时已经了解了,现在又有些新的感悟,将其总结在此,有新的体会会继续总结的!

面向对象与过程


一、类和实例

类:英文名字Class,有“类别",“分类",“聚类"的意思。必须牢记类是用来描述具看相同屡性和方法的对象的模板,比如学生都有名字、分数,他们有着共同的属性。这时我们就可以设计一个学生类,用于记录学生的名字和分数

  • 属性(Attribute):类里面用于描述所有对象共同特征的变量或数据。比如学生的名字和分数。
  • 方法(Method):类里面的函数,用来区别类外面的函数,用来实现某些功能。比如打印出学生的名字和分数。
# 创建一个学生类
class  Student:
    # 定义属性,初始化方法
    def __init__(self,name,score):
        self.name = name
        self.score = score
    def show(self):
        print(' 的成绩为'.format(self.name,self.score))
# 创建实例化对象
zs = Student('bobo',100)
ju = Student('jayu',99)

zs.show()

bobo 的成绩为100


二、实例变量和类变量

假设我们需要在Student类里增加一个计数器number,每当一个新的学生对象(Object)被创建时,这个计数器就自动加1,由于这个计数器不属于某个具体学生,而属于Student类的,所以被称为类变量(Class variables),而姓名和分数属于每个学生对象的,所以属于实例变量(nstance variables),也被称为对象变量(object variables).

# 创建一个学生类
class  Student:
    
    # number 属于类变量,定义在方法外,不属于具体实例
    number = 0
    
    # 定义属性,初始化方法
    def __init__(self,name,score):
        self.name = name
        self.score = score
        # 访问类变量
        Student.number = Student.number+1
        
    def show(self):
        print(' 的成绩为'.format(self.name,self.score))

类变量和实例变量的区别很大,访问方式也也不一样:

  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。访问或调用类变量的正确方式是类名.变量名
  • 实例变量:定义在方法中的变量,属于某个具体的对象。访问或调用实例变量的正确方式是对象名.变量名或者self.变量名
  • 访问类变量
zs = Student('bobo',100)
Student.number

1

ju = Student('jayu',99)
Student.number

2

zs.number # 这里用类实例.类变量也可以调用成功 (此方式不推荐使用)

2

不推荐使用类实例.类变量的原因:Python类变量和实例变量(类属性和实例属性)

  • 访问实例变量
sc = Student('cusi',98)
print(sc.name,sc.score)

cusi 98

  • 添加实例变量

Python动态语言的特点,让我们可以随时给实例添加新的实例变量,给类添加新的类变量和方法。
因此,在使用li.classroom =102的时候,要么是给已有的实例变量classroom重新赋值,要么就是新建一个i专属的实例变量classroom并賦值为102.

s4 = Student('lisi',120)
s4.name
s4.address = 'Bj'
print(s4.address)

Bj

对于s4是存在address的变量,但是对于其他变量来说是不存在的:


三、静态方法

静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系(比如我想定义一个关于时间操作的类,其中有一个获取当前时间的函数),也就是说在静态方法中,不会涉及到类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。

静态方法由类调用,无默认参数。将实例方法参数中的self去掉,然后在方法定义上方加上@staticmethod,就成为静态方法。它属于类,和实例无关。建议只使用类名.静态方法的调用方式。(虽然也可以使用实例名.静态方法的方式调用)

import time 
class TimeTest:
    def __init__(self,hour,minute,scond):
        self.hour = hour 
        self.minute = minute
        self.second = second
    @staticmethod
    def showTime():
        return time.strftime("%H:%M:%S",time.localtime())

print(TimeTest.showTime())

11:35:45


四、封装、继承和多态

面向对象编程有三大重要特征:封装、继承和多态。

4.1 封装

封装是指将数据(属性)与具体操作的实现代码(方法)放在封装到类的内部,从而可以使这些代码的实现细节不被外界发现,外界只能通过接口使用类内部封装的数据,而不能通过任何形式修改其内部实现,正是由于封装机制,程序在使用某一个类创建的对象时不需要关心该对象的数据结构细节及实现操作的方法。 使用封装能隐藏对象实现细节,使代码更易维护,同时因为不能直接调用和修改对象内部的私有信息,在一定程度上保证了系统安全性。

4.2 继承

现实中的继承

  • 继承来源于现实世界,一个最简单的例子就是孩子会具有父母的一些特征,即每个孩子都会继承父亲或者母亲的某些特征,当然这只是最基本的继承关系,现实世界中还存在着更复杂的继承。

面向对象的继承

  • 面向对象的继承机制实现了代码的复用,多个类公用的代码部分可以只在一个类中提供,而其他类只需要继承这个类即可。
  • 继承关系
    • 子类:当我们定义一个新类的时候,新的类称为子类(Subclass)
    • 父类:被继承的类称为基类、父类或超类(Base class,Super class)

继承的基本特性

  • 继承最大的好处是子类获得了父类的全部变量和方法的同时,又可以根据需要进行修改、拓展。

继承的语法机制

  • 在子类名后面的括号中加入父类的类名即可
import  time
class Animal:
    number = 0 #类变量
    def __init__(self,age,color):
        self.age = age 
        self.color = color
        Animal.number = Animal.number + 1
    def show(self): # 方法
        print('age: ; color:'.format(self.age,self.color))
    @classmethod
    def total(cls): # 类方法
        print("Total:0".format(cls.number))
        
    @staticmethod
    def showTime(): # 静态方法
        return time.strftime("%H:%M:%S",time.localtime())

class Dog(Animal):
    pass
d = Dog(10,'red') # 继承父类构造方法

print(d.color) # 继承父类的实例变量和类变量
print(d.number)  # 不建议这样使用
# 继承父类的静态方法、类方法、和成员方法
d.show()
d.total()
d.showTime()  

red
1
age:10 ; color:red
Total:1
‘11:57:30’


五、super()函数⭐

我们都知道,在子类中如果有与父类同名的成员,那就会覆盖掉父类里的方法(重写父类方法),那如果你想在子类的类中强制调用父类的成员该如何实现呢?使用supero函数!这是一个非常重要的函数,最常见的就是通过super调用父类的实例化方法init

语法

  • super(子类名,self).方法名(),需要传入的是子类名和self,调用的是父类里的方法,按父类的方法需要传入参数。
  • 当然也可以简化直接使用super.方法名()
# 重写父类方法
class A:
    def __init__(self,name):
        self.name = name
    def like(slef):
        print('smoke')
        print('drink')
    
class B(A):
    def like(self):
        print('games')

obj = B('jack')
obj.like()

games

# 重写父类方法
class A:
    def __init__(self,name):
        self.name = name
    def like(slef):
        print('smoke')
        print('drink')
    
class B(A):
    def like(self):
        # super(B,self).like()
        super().like()  #===============#
        print('games')

obj = B('jack')
obj.like()

smoke
drink
games

  • super()的作用之一:继承父类的构造方法⭐
# 重写父类方法
class A:
    def __init__(self,name):
        self.name = name
        print("父类的__init__方法执行了!")
    def like(slef):
        print('smoke')
        print('drink')
    
class B(A):
    
    def __init__(self,name,age):
        super(B,self).__init__(name=name) # 必须加上name否则报错
        self.age = age
        
    def showlike(self):
        super().like()
        print('games')

obj = B('jack',17)
obj.showlike()

父类的__init__方法执行了!
smoke
drink
games


以上是关于Python面向对象编程_类的主要内容,如果未能解决你的问题,请参考以下文章

python学习day11 面向对象编程 类和实例

Python面向对象封装案例

python中 _____xx__() 区别及使用场景

面向对象封装案例 二

Python面向对象封装案例

Python面向对象高级编程-__slots__定制类,枚举