Two, python programming advanced 04: object-oriented programming

Table of contents

1. Object-oriented programming ideas

2. Object-oriented terminology

3. Basic use of classes and objects

3.1 Define a class

3.2 Creation of class objects

3.3 Use of class objects

3.4 The self parameter of the class method

3.5 __init__() class construction method

3.6 Class variables and instance variables (class attributes and instance attributes)

3.7 Instance methods, static methods, and class methods

4. Class encapsulation mechanism

5. Class inheritance mechanism

6. Parent class method rewriting


1. Object-oriented programming ideas

Object-oriented programming - Object Oriented Programming, referred to as OOP, is a programming idea. OOP regards the object as the basic unit of the program, and an object contains data and functions for manipulating data.

Process-oriented programming regards a computer program as a series of command sets, that is, the sequential execution of a set of functions. In order to simplify the program design, the process-oriented function is divided into sub-functions, that is, the complexity of the system is reduced by cutting the large-block functions into small-block functions.

Object-oriented programming regards a computer program as a collection of objects, and each object can receive messages sent by other objects and process these messages. The execution of a computer program is a series of messages transmitted between objects .

From the beginning, Python was designed to support object-oriented programming languages, so Python can be programmed in an object-oriented manner. Moreover, Python's object-oriented is relatively simple. It does not provide a large number of complicated object-oriented features like other object-oriented languages. It is committed to providing simple and sufficient grammatical functions.

In Python, all data types can be regarded as objects, and of course you can customize objects. The custom object data type is the concept of class (Class) in object-oriented.

It is easy to create a class and object in  Python . Python supports three major object-oriented features: encapsulation, inheritance, and polymorphism. Subclasses inheriting the parent class can also inherit the variables and methods of the parent class.

2. Object-oriented terminology

(1) Class (Class):  Used to describe a collection of objects with the same properties and methods. It defines properties and methods common to every object in the collection. Objects are instances of classes.

(2) Method: the function defined in the class.

(3) Class variables : Class variables are common to all instantiated objects. Class variables are defined within the class and outside the body of the function. Class variables are generally not used as instance variables.

(4) Data members : class variables or instance variables are used to process data related to the class and its instance objects.

(5) Method rewriting : If the method inherited from the parent class cannot meet the needs of the subclass, it can be rewritten. This process is called method override, also known as method rewriting.

(6) Local variables : Variables defined in methods only apply to the class of the current instance.

(7) Instance variables : In the declaration of the class, attributes are represented by variables, which are called instance variables, and instance variables are  variables modified with self .

(8) Inheritance : That is, a derived class inherits the fields and methods of the base class. Inheritance also allows an object of a derived class to be treated as an object of a base class. For example, there is such a design: an object of type Dog is derived from the Animal class, which simulates the "is-a" relationship (for example, Dog is an Animal).

(9) Instantiation : Create an instance of a class, a specific object of the class.

(10) Object : An instance of a data structure defined by a class. Objects consist of two data members (class variables and instance variables) and methods.

Compared with other programming languages, Python adds a class mechanism without adding new syntax and semantics as much as possible.

Classes in Python provide all the basic functions of object-oriented programming: the inheritance mechanism of classes allows multiple base classes, derived classes can override any method in the base class, and methods can call methods with the same name in the base class.

Objects can contain any amount and type of data.

3. Basic use of classes and objects

3.1 Define a class

The most important concepts of object-oriented are class (Class) and instance (Instance). It must be kept in mind that a class is an abstract template , and an instance is a specific "object" created based on a class. Each object has the same method. , but their respective data may differ. In Python, classes are defined with the class keyword:

#!/usr/bin/python3

class class name: class attribute... class method...

class MyClass:i = 12345

Note that the order in which attributes and methods are located in the class has no effect, and members can call each other.

Python 's class definition is a bit like a function definition. It starts with a colon (:) as the class body, and uses the uniform indentation part as the class body. The difference is that function definitions use the def keyword, while class definitions use the class keyword.

Python 's class definition consists of a class header (referring to the class keyword and the class name part) and a uniformly indented class body. The two most important members in the class body are attributes and methods. If no attributes and methods are defined for the class, the class is equivalent to an empty class. If the empty class does not require other executable statements, the pass statement can be used as a placeholder.

For example, the following class definitions are allowed:

class Wbyq:

pass

3.2 Creation of class objects

Using  the class statement can only create a class, but not the object of the class. Therefore, if you want to use the created class, you need to manually create the object of the class. The process of creating a class object is also called the instantiation of the class .

Sample code: instantiate the created class

#!/usr/bin/python3

# create a class

class MyClass:

    data=666

    def funcname(self, parameter_list):

       print("Incoming parameters:", parameter_list)

#Instance class: create object

wbyq=MyClass()

3.3 Use of class objects

The grammatical format of using the created class object to access the instance variable in the class: object name. variable name

The grammatical format of using a class object to call a method in a class: object name. method name (parameter)

Note that object names, variable names and method names are connected with dots ".".

(1) Example: accessing members of a class

#!/usr/bin/python3

# create a class

class MyClass:

    data=666

    def funcname(self, parameter_list):

       print("Incoming parameters:", parameter_list)

#Instance class: create object

wbyq=MyClass()

print("data=", wbyq.data) #Access the members of the class, use the dot

wbyq.funcname("hello world.")

Result: data=666

Incoming parameters: hello world.

Python not only supports accessing variables already defined in the class, but also supports dynamically adding variables to created objects. Note: Adding and deleting variables is only for the object itself, and has no effect on the class template.

(2) Example: Dynamically add and delete variables

#!/usr/bin/python3

# create a class

class MyClass:

    data1=666

    data2=888

   

#Instance class: create object

wbyq=MyClass()

wbyq.data1=123

wbyq. data2=456

wbyq. data3=789

print("data1=",wbyq.data1)

print("data2=",wbyq.data2)

print("data3=",wbyq.data3)

#Instance class: create object

xl=MyClass()

print("data1=",xl.data1)

print("data2=",xl.data2)

#print("data3=",xl.data3)  #无法访问,因为类里没有data3这个变量

# 删除wbyq对象的name实例变量

del wbyq.data1

del wbyq.data2

del wbyq.data3 #删除变量之后无法再访问

#print("data1=",wbyq.data1)

#print("data2=",wbyq.data2)

#print("data3=",wbyq.data3)

3.4 类方法的self参数

Python 要求,类方法(构造方法和实例方法)中至少要包含一个参数,但并没有规定此参数的名称(完全可以叫任意参数名),上面代码里将类方法的第一个参数命名为 self,只是 Python 程序员约定俗成的一种习惯,这会使程序具有更好的可读性,Python 类方法中的 self 参数就相当于 C++ 中的 this 指针。

同一个类可以产生多个对象,当某个对象调用类方法时,该对象会把自身的引用作为第一个参数自动传给该方法

对于构造方法来说,self 参数(第一个参数)代表该构造方法正在初始化的对象,程序在调用实例方法和构造方法时,不需要为第一个参数传值。

示例: 区分是哪个对象调用了类的方法

#!/usr/bin/python3

#创建一个类

class MyClass:

    data=666

    def func(self):

       print("调用func方法的对象是:", self)

#实例类:创建对象

wbyq1=MyClass()

wbyq1.func()

#实例类:创建对象

wbyq2=MyClass()

wbyq2.func()

结果:

调用func方法的对象是: <__main__.MyClass object at 0x000001A02C9EA280>

调用func方法的对象是: <__main__.MyClass object at 0x000001A02CB33640>

(2)、示例: 使用self访问类属性成员

#!/usr/bin/python3

#创建一个类

class MyClass:

    data1=666

    data2=888

    def func(self):

       print("data1=", self.data1)  #使用self访问类属性成员

       print("data2=", self.data2)  #使用self访问类属性成员

#实例类:创建对象

wbyq=MyClass()

wbyq.func()

(3)、示例: self完全可以设置为任意参数名,self名称只是 Python程序员约定的一种习惯

#!/usr/bin/python3

#创建一个类

class MyClass:

    data1=666

    data2=888

    def func(data): #可以任意命名,不一定非的是self

       print("data1=", data.data1) #使用self访问类属性成员

       print("data2=",data.data2) #使用self访问类属性成员

#实例类:创建对象

wbyq=MyClass()

wbyq.func()

3.5 __init__()类构造方法

在创建类时,可以手动添加一个 __init__() 方法,该方法是一个特殊的类实例方法,称为构造方法(或构造函数)。

构造方法用于创建对象时使用,每当创建一个类的实例对象时,Python 解释器都会自动调用它。

Python 类中,添加构造方法的语法格式:

def __init__(self,...):

代码块

注意,此方法的方法名中,开头和结尾各有 2 个下划线,且中间不能有空格。Python 中很多这种以双下划线开头、双下划线结尾的方法,都具有特殊的意。

另外,__init__() 方法可以包含多个参数,但必须包含一个名为 self 的参数,且必须作为第一个参数。也就是说,类的构造方法最少也要有一个 self 参数。

如果开发者没有该类定义任何构造方法,那么 Python 会自动为该类创建一个只包含 self 参数的默认的构造方法。示例代码:

#!/usr/bin/python3

#创建一个类

class MyClass1:

    def __init__(self):

       print("调用构造函数")

#实例类:创建对象

wbyq1=MyClass1() #创建对象的时候,自动调用方法__init__()

#创建一个类

class MyClass2:

    def __init__(self,list):

       print("构造函数收到的形参:",list)

#实例类:创建对象

wbyq2=MyClass2("hello world")

结果:调用构造函数

构造函数收到的形参: hello world

3.6 类变量和实例变量(类属性和实例属性)

无论是在类中定义的属性还是方法,在类的外部,都无法直接调用它们,完全可以把类看做是一个独立的作用域(称为类命名空间),则类属性其实就是定义在类命名空间内的变量类方法其实就是定义的类命名空间中的函数)。

根据定义属性的位置不同,类属性又可细分为类属性(类变量)和实例属性(实例变量)。

(1)、类变量指的是定义在类中,在类方法外的变量

类变量的特点是:所有类的实例化对象都可以共享类变量的值,即类变量可以在所有实例化对象中作为公用资源,当一个对象修改了类变量的值,其他对象访问类变量的值也会改变。

在类的方法中,访问类变量可以使用,类名.变量名的方式进行访问或者使用self (对象引用)访问。示例代码:

#!/usr/bin/python3

#创建一个类

class MyClass:

    data=123

    def func1(self,list):

       MyClass.data=list #修改类变量的值 

    def func2(self):

       print("data=", MyClass.data)  #打印类变量的值

#实例类:创建对象

wbyq1=MyClass()

wbyq2=MyClass()

#访问类成员

wbyq1.func2()

wbyq2.func2()

wbyq1.func1(888)

wbyq1.func2()

wbyq2.func2()

(2)、实例变量指的是定义在类的方法中的属性,它的特点是: 只作用于调用方法的对象。实例变量只能通过对象名访问,无法通过类名直接访问

Python允许通过对象访问类变量,但无法通过对象修改类变量的值。因为,通过对象修改类变量的值,不是在给“类变量赋值”,而是定义新的实例变量。示例代码:

#!/usr/bin/python3

#创建一个类

class MyClass:

    def func1(self,list):

       data=123

       self.data=list #无法修改类变量的值,相当于定义新的实例变量      

       print("data=",MyClass.data) #访问新的实例变量  

    def func2(self):

       print("data=",MyClass.data) #打印类变量的值

#实例类:创建对象

wbyq=MyClass()

wbyq.func1(666)

wbyq.func2()

3.7 实例方法、静态方法和类方法

类属性可细分为类属性和实例属性,类中的方法也可以分为类方法、实例方法和静态方法。

(1)、Python类实例方法

通常情况下,在类中定义的方法默认都是实例方法。

实例方法最大的特点就是,它最少也要包含一个 self 参数,用于绑定调用此方法的实例对象,实例方法通常会用类对象直接调用,当然也可以用类名调用,使用类名调用时,方法第一个参数需要显式传递(对象)。示例代码:

#!/usr/bin/python3

#创建一个类

class MyClass:

    def funcn(self, parameter_list):

       print(parameter_list)

#实例类:创建对象

wbyq=MyClass()

#通过对象名调用实例方法

wbyq.funcn("通过对象名调用实例方法")

#通过类名调用实例方法

MyClass.funcn(wbyq,"通过类名调用实例方法")  #第一个参数需要显式传递

(2)、Python类方法

Python类方法和实例方法相似,它最少也要包含一个参数,只不过,类方法中通常将其命名为 cls,且 Python 会自动将类本身绑定给 cls 参数(而不是类对象)。因此,在调用类方法时,无需显式为 cls 参数传参,和 self 一样,cls 参数的命名也不是规定的(可以随意命名),只是 Python 程序员约定俗称的习惯而已。

类方法定义和实例方法最大的不同在于,类方法需要使用@classmethod进行修饰:示例代码:

#!/usr/bin/python3

#创建一个类

class MyClass:

    @classmethod

    def funcn(cls,parameter_list):

       print("类方法:",parameter_list)

#使用类名调用类方法,第一个参数不需要显示传递

MyClass.funcn("hello world.")

注意,如果没有 @classmethod,Python 解释器会将funcn ()方法认定为实例方法,而不是类方法。

(3)、Python类静态方法

静态方法,其实就是函数,和函数唯一的区别是,静态方法定义在类这个空间(类命名空间)中,而函数则定义在程序所在的空间(全局命名空间)中。

静态方法没有类似 self、cls 这样的特殊参数,因此 Python 解释器不会对它包含的参数做任何类或对象的绑定,也正是因为如此,此方法中无法调用任何类和对象的属性和方法。静态方法需要使用@staticmethod修饰。

示例代码:

#!/usr/bin/python3

#创建一个类

class MyClass:

    @staticmethod

    def func(parameter_list):

       print(parameter_list)

#使用类名调用类方法

MyClass.func("使用类名调用类方法")

#使用对象调用静态方法

wbyq=MyClass()

wbyq.func("使用对象调用静态方法")

结果:使用类名调用类方法

使用对象调用静态方法

4. 类封装机制

封装(Encapsulation)是面向对象的三大特征之一(另外两个是继承和多态),它指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。

封装机制保证了类内部数据结构的完整性,因为使用类的用户无法直接看到类中的数据结构,只能使用类允许公开的数据,很好地避免了外部对内部数据的影响,提高了程序的可维护性。

对一个类或对象实现良好的封装,可以达到以下目的:

(1)、隐藏类的实现细节。

(2)、让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里加入控制逻辑,限制对属性的不合理访问。

(3)、可进行数据检查,从而有利于保证对象信息的完整性。

(4)、便于修改,提高代码的可维护性。

为了实现良好的封装,需要从以下两个方面来考虑:

(1)、将对象的属性和实现细节隐藏起来,不允许外部直接访问。

(2)、把方法暴露出来,让方法来控制对这些属性进行安全的访问和操作。

实际上封装有两个方面的含义:把该隐藏的隐藏起来,把该暴露的暴露出来。

Python 并没有提供类似于其他语言的 private 修饰符,如果想要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__。

在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。

示例代码: 定义私有变量

#!/usr/bin/python3

#创建一个类

class MyClass:

#定义私有变量,外部无法使用

    __data=888

    def funcname(self):

       print("__data=", self.__data)

       print("__data=", MyClass.__data)

#创建对象

wbyq=MyClass()

wbyq.funcname()

#print(wbyq.__data)#无法访问:AttributeError: 'MyClass' object has no attribute '__data'

使用私有变量确保了外部代码不能随意修改对象内部的状态,通过访问限制的保护,代码更加健壮。

如果又要允许外部代码修改私有变量,可以增加一个方法间接访问

#!/usr/bin/python3

#创建一个类

class MyClass:

    __data=888  #定义私有变量

    def func(self, data):

       if 50<data<100:

           MyClass.__data=data  #修改私有变量

       else:

           raise ValueError('范围错误')

#创建对象

wbyq=MyClass()

wbyq.func(60)

在方法中间接修改私有变量,可以对参数做检查,避免传入无效的参数。

5. 类继承机制

继承是面向对象的三大特征之一,也是实现代码复用的重要手段。

继承经常用于创建和现有类功能类似的新类或者是新类只需要在现有类基础上添加一些成员(属性和方法)。

Python 中,实现继承的类称为子类,被继承的类称为父类(也可称为基类)。

子类继承父类的语法是:在定义子类时,将多个父类放在子类之后的圆括号里。语法格式如下:

class 类名(父类1, 父类2, ...)

类定义部分

Python 的继承是多继承机制,一个子类可以同时拥有多个直接父类。

定义子类,只需在原来的类定义后增加圆括号,并在圆括号中添加多个父类,表明该子类继承了这些父类。如果在定义一个 Python 类时,并未显式指定这个类的直接父类,则这个类默认继承 object 类,object 类是所有类的父类,要么是直接父类,要么是间接父类。

示例代码:

#!/usr/bin/python3

class MyClass1:

    def func1(self, parameter_list):

       print("我是父类1",parameter_list)

class MyClass2:

    def func2(self, parameter_list):

       print("我是父类2",parameter_list)

class MyClass3(MyClass1,MyClass2):   

    def func3(self, parameter_list):

       print("我是子类",parameter_list)

#创建对象

wbyq=MyClass3()

wbyq.func1("hello world.") #从父类继承的方法

wbyq.func2("hello world.") #从父类继承的方法

wbyq.func3("hello world.")

需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python会从左至右搜索,就是说方法在子类中未找到时,从左到右查找父类中是否包含方法,如果没有找到就抛出异常。

示例代码:

#!/usr/bin/python3

class MyClass1:

    def func(self, parameter_list):

       print("我是父类1:",parameter_list)

class MyClass2:

    def func(self, parameter_list):

       print("我是父类2:",parameter_list)

class MyClass3(MyClass1,MyClass2):

    pass   

    #def func(self, parameter_list):   

    #    print("我是子类:",parameter_list)

#创建对象

wbyq=MyClass3()

wbyq.func("hello world.")

Python 子类继承父类构造函数说明:

(1)、子类需要自动调用父类的方法:子类不重写__init__()方法,实例化子类后,会自动调用父类的__init__()的方法。

(2)、子类不需要自动调用父类的方法:子类重写__init__()方法,实例化子类后,将不会自动调用父类的__init__()的方法。

(3)、子类重写__init__()方法又需要调用父类的方法:使用super关键词。

语法: super(子类,self).__init__(参数1,参数2,....)

示例:

class MyClass2(MyClass1): 

def __init__(self, name): 

super(MyClass2, self).__init__(name)

 

6. 父类方法重写

当子类和父类都存在相同的方法时,子类的方法就会覆盖父类方法,在代码运行的时候,总是会调用子类的方法。这种子类包含与父类同名的方法的现象被称为方法重写(Override),也被称为方法覆盖。可以说子类重写了父类的方法,也可以说子类覆盖了父类的方法。

(python中可以忽略多态,Python原生就是多态,print(arg)  #形态不固定,字符串,数字...都行)

示例代码: 父类方法重写

#!/usr/bin/python3

class MyClass1:

    def func(self, parameter_list):

       print("我是父类", parameter_list)

class MyClass2(MyClass1):

    def func(self, parameter_list):

       print("我是子类", parameter_list)

#创建对象

wbyq=MyClass2()

wbyq.func("hello world.")

结果:我是子类 hello world.

如果父类方法的功能不能满足需求时,就可以在子类重写父类的方法。

如果子类重写了父类的方法之后,想要再次调用父类的方法,可以使用super函数。super() 函数是用于调用父类(超类)的一个方法。

示例:

#!/usr/bin/python3

class MyClass1:

         def func(self, parameter_list):

                   print("我是父类1:",parameter_list)

class MyClass2:

         def func(self, parameter_list):

                   print("我是父类2:",parameter_list)

class MyClass3(MyClass1,MyClass2):

         def func(self, parameter_list):

                   super().func(parameter_list)  #调用父类

#创建对象

wbyq=MyClass3()

wbyq.func("hello world.")

结果:我是父类1: hello world.

Guess you like

Origin blog.csdn.net/qq_40088639/article/details/128569152