Python之面向对象程序设计

1、类定义

面向对象程序设计的一个关键性观念是将数据以及对数据的操作封装在一起,组成一个相互依存、不可分割的整体,即对象。对于相同类型的对象进行分类、抽象后,得出共同的特征而形成了类,面向对象程序设计的关键就是如何合理地定义和组织这些类以及类之间的关系

Python完全采用了面向对象程序设计的思想,是真正面向对象的高级动态编程语言,完全支持面向对象的基本功能,如封装、继承、多态以及对基类方法的重写(覆盖)



1.1、规范:

类名、实例名和模块名要规范,并在整个系统中保持风格一致。 类名一般推荐用大驼峰式命名法(每个单词的首字母大写,并且不使用下划线),实例名和模块名推荐下划线命名法(又称蛇形命名法,全小写,并在单词之间加上下划线

每个类定义后的第一行和模块文件的首行,都应包含一个说明性字符串,简要描述类的功能。

使用两个空行来分隔不同类,使用一个空行分隔类内的不同方法

当使用 import 语句时,使用一个空行分隔标准库和自己的库


1.2、类的定义

class 关键字用于定义类
由于是新定义的全新类,所以类名后面直接跟冒号。也可以是class Dog:
一般类名以大写字母开头
紧随其后的是类的功能描述(不是必需)

构造函数( __init__()
和定义其他函数一样,也使用 def 关键字。
该函数有一些特殊的地方:
函数名的开头和末尾各有两个下划线。这是一种约定,旨在避免命名冲突。
每次创建 Dog 类的实例, Python 都会自动运行这个函数
一般称之为初始化方法或构造函数

init()函数的函数体

第一行是说明性注释
第二行定义的私有变量以 self. 为前缀
这个私有变量可在类的内部所有方法中通过同样的 self. 前缀来使用
但在类的外部不能直接访问,需要特殊方法访问

class Dog(object):
    def __init__(self, nick):
        """初始化私有数据成员(变量) nick"""
        self.__nick = nick


    def show_info(self):
        print(f"My dog's nick is {
      
      my_dog.__nick}.")


    def roll_over(self):
        """模拟小狗收到命令时打滚"""
        print(f"{
      
      self.__nick} rolled over!")


my_dog= Dog("爪爪")
my_dog.roll_over()
my_dog.show_info()

2、创建实例

通过箭头处的代码:
创建了一条昵称为 '爪爪’的小狗。
不需要传入 self 实参, Python 会在调用初始化方法时自动传入它
通过接收实参,初始化方法将会设置 nick数据成员,表示小狗的昵称,随后返回表示小狗的实例
最后将这个实例赋值给 my_dog 变量

my_dog=Dog("爪爪")

创建类的实例后,使用点号语法来调用实例的方法,从而让实例“动起来”
Python 会在类中查找调用的方法,然后运行方法体中的语句

my_dog = Dog('爪爪')
my_dog.roll_over()

3、属性

class Car(object):   
    def __init__(self, make,year):
        self.__make = make
        self.__year = year
        self.__price = 0
        
    def get_describe(self):
        long_name = f"{
      
      self.__make}-{
      
      self.__year}-{
      
      self.__price}"
        return long_name.title()

    def __get(self):
        return self.__price 
    def __set(self, v):
        self.__price = v
    Price = property(__get, __set)
car = Car('audi', 2023)
car.Price=10000
print(car.get_describe(),car.Price)

>>> #只读,无法修改和删除
class Test:
    def __init__(self, value):
        self.__value = value    
    def __get(self):
        return self.__value
    value = property(__get)
>>> t = Test(3)
>>> t.value
3
>>> t.value = 5                        #只读属性不允许修改值
AttributeError: can't set attribute
>>> t.v=5              #动态增加新成员
>>> t.v
5
>>> del t.v            #动态删除成员
>>> del t.value        #试图删除对象属性,失败
AttributeError: can't delete attribute
>>> t.value
3

4、方法

静态方法和类方法都可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。
静态方法和类方法不属于任何实例,不会绑定到任何实例,当然也不依赖于任何实例的状态,与实例方法相比能够减少很多开销。
类方法一般以cls作为类方法的第一个参数表示该类自身,在调用类方法时不需要为该参数传递值,静态方法则可以不接收任何参数。

>>> class Root:
    __total = 0
    def __init__(self, v):    #构造方法
        self.__value = v
        Root.__total += 1

    def show(self):           #普通实例方法
        print('self.__value:', self.__value)
        print('Root.__total:', Root.__total)

    @classmethod              #修饰器,声明类方法
    def classShowTotal(cls):  #类方法
        print(cls.__total)

    @staticmethod             #修饰器,声明静态方法
    def staticShowTotal():    #静态方法
        print(Root.__total)
        
>>> r = Root(3)
>>> r.classShowTotal() #通过对象来调用类方法
1
>>> r.staticShowTotal() #通过对象来调用静态方法
1
>>> r.show()
self.__value: 3
Root.__total: 1
>>> Root.classShowTotal()  #通过类名调用类方法
2
>>> Root.staticShowTotal() #通过类名调用静态方法
2

5、继承

在编写类时,并非总是要从头开始,如果要编写的类是一个已有类的特殊版本,则我们可以使用继承(inheritance)
被继承的类称为父类(parent class),而继承的类称为子类(child class)
子类可以继承父类的所有属性和方法,也可以定义自己的属性和方法

下面来模拟电动汽车,电动汽车是一种特殊的汽车,和之前的汽车一样,它也有里程表,也需要能够显示信息。
因此可在之前 Car 类的基础上,创建它的继承类 ElectricCar。
使用继承后,只需为电动汽车特有的属性和行为编写代码即可。

class Car(object):   
    def __init__(self, make,year):
        self.__make = make
        self.__year = year
        self.__price = 0        
    def get_describe(self):
        long_name = f"{
      
      self.__make}-{
      
      self.__year}-{
      
      self.__price}"
        return long_name.title()

    def __get(self):
        return self.__price 
    def __set(self, v):
        self.__price = v
    Price = property(__get, __set)

6、多态

当父类中定义的一些方法不能满足子类的要求时,可以在子类中随时重写父类的方法:定义一个同名的方法
当调用子类生成的实例时,Python 首先会查找子类中的方法,从而忽略父类中被重写的同名方法
所谓多态(polymorphism),是指基类的同一个方法在不同派生类对象中具有不同的表现和行为。派生类继承了基类行为和属性之后,还会增加某些特定的行为和属性,同时还可能会对继承来的某些行为进行一定的改变,这都是多态的表现形式。

class Car(object): 
    def show(self):
       print("car...")


class ElectricCar(Car):
    def show(self):
        print("electric car...")    

car = Car()
car.show()

ec=ElectricCar()
ec.show()
>>> class Animal(object):      #定义基类
    def show(self):
        print('I am an animal.')

>>> class Cat(Animal):         #派生类,覆盖了基类的show()方法
    def show(self):
        print('I am a cat.')
>>> class Dog(Animal):         #派生类
    def show(self):
        print('I am a dog.')

>>> class Test(Animal):        #派生类,没有覆盖基类的show()方法
       pass

7、组合

随着属性和方法越来越多,类定义的代码行可能会越来越长。
为了解决这一问题,我们可以将类中的一部分属性和方法提取出来,作为一个独立的类,这种方法称为组合(composition):

class Car(object):   
    def __init__(self, year):
        self.__year = year
    def get_describe(self):
        s = f"{
      
      self.__year}"
        return s.title()
    
class Battery:
    def __init__(self, size=40):
        self.size = size
    def describe_battery(self):
        print(f"{
      
      self.size}-kWh battery.")

8、导入类

为了避免一个文件中包含过多的类,可以把不同类存储在不同文件中。
例如, Car类放在Class_car07_part1文件中,而ElectricCar类放在Class_car07_part2文件中,并在开头加一句代码

from Class_car07_part1  import Car

class ElectricCar(Car):
    def __init__(self, year,price):
    ……

猜你喜欢

转载自blog.csdn.net/qq_52108058/article/details/134980465