面向对象技术简介
- 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 类变量: 类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 局部变量:定义在方法中的变量,只作用于当前实例的类。
- 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
- 实例化:创建一个类的实例,类的具体对象。
- 方法:类中定义的函数。
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
摘要
根据类来创建对象被称为实例化 ,这让你能够使用类的实例。在 本章中,你将编写一些类并创建其实例。你将指定可在实例中存储 什么信息,定义可对这些实例执行哪些操作。你还将编写一些类来 扩展既有类的功能,让相似的类能够高效地共享代码。你将把自己 编写的类存储在模块中,并在自己的程序文件中导入其他程序员编写的类。
1 创建和使用类
根据Dog 类创建的每个实例都将存储名字和年龄。我们赋予了每条小狗蹲下(sit() )和打滚(roll_over() )的能力:
我们将方法__init__() 定义成了包含三个形参:self 、name 和age 。在这个方法的定义中,形参self 必不可少,还必须位于其他形参的 前面。为何必须在方法定义中包含形参self 呢?因为Python调用这 个__init__() 方法来创建Dog 实例时,将自动传入实参self 。每个与 类相关联的方法调用都自动传递实参self ,它是一个指向实例本身的 引用,让实例能够访问类中的属性和方法。我们创建Dog 实例时, Python将调用Dog 类的方法__init__() 。我们将通过实参向Dog() 传 递名字和年龄;self 会自动传递,因此我们不需要传递它。每当我们 根据Dog 类创建实例时,都只需给最后两个形参(name 和age )提供值。
class Dog(): #定义一个名为Dog的类
"""一次模拟小狗的简单尝试"""#编写了一个文档字符串,对这个类的功能作了描述
def __init__(self, name, age): # __init__() 是一个特殊的方法,每当你根据Dog 类创建新实例时, Python都会自动运行它。
"""初始化属性name和age"""
self.name = name
self.age = age
def sit(self):# Dog 类还定义了另外两个方法:sit() 和roll_over()
"""模拟小狗被命令时蹲下"""
print(self.name.title() + " is now sitting.")
def roll_over(self):
"""模拟小狗被命令时打滚"""
print(self.name.title() + " rolled over!")
根据类创建实例
注意: self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。self 代表的是类的实例,代表当前对象的地址。
我们让Python创建 一条名字为’willie’ 、年龄为6 的小狗。遇到这行代码时,Python使 用实参’willie’ 和6 调用Dog 类中的方法__init__() 。方法 init() 创建一个表示特定小狗的示例,并使用我们提供的值来设 置属性name 和age 。方法__init__() 并未显式地包含return 语句, 但Python自动返回一个表示这条小狗的实例。我们将这个实例存储在变 量my_dog 中。在这里,命名约定很有用:我们通常可以认为首字母大 写的名称(如Dog )指的是类,而小写的名称(如my_dog )指的是根 据类创建的实例。
class Dog(): #定义一个名为Dog的类
"""一次模拟小狗的简单尝试"""#编写了一个文档字符串,对这个类的功能作了描述
def __init__(self, name, age): # __init__() 是一个特殊的方法,每当你根据Dog 类创建新实例时, Python都会自动运行它。
"""初始化属性name和age"""
self.name = name
self.age = age
def sit(self):# Dog 类还定义了另外两个方法:sit() 和roll_over()
"""模拟小狗被命令时蹲下"""
print(self.name.title() + " is now sitting.")
def roll_over(self):
"""模拟小狗被命令时打滚"""
print(self.name.title() + " rolled over!")
my_dog = Dog('willie', 6)#Python使用实参'willie' 和6调用Dog 类中的方法__init__() 。
#方法 __init__() 创建一个表示特定小狗的示例,并使用我们提供的值来设 置属性name和age 。
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")
#打印结果
My dog's name is Willie.
My dog is 6 years old.
访问属性
在上例中使用句点法来访问属性。
my_dog.name
my_dog.age
在这里,Python先找到实例my_dog ,再查找与这个实例相关联的 属性name 。在Dog 类中引用这个属性时,使用的是self.name 。
你也可以使用以下函数的方式来访问属性:
- getattr(obj, name[, default]) : 访问对象的属性。
- hasattr(obj,name) : 检查是否存在一个属性。
- setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
- delattr(obj, name) : 删除属性。
调用方法
根据Dog 类创建实例后,就可以使用句点表示法来调用Dog 类中定义的 任何方法。下面来让小狗蹲下和打滚:
my_dog = Dog('willie', 6)
my_dog.sit()
my_dog.roll_over()
#打印结果
Willie is now sitting.
Willie rolled over!
创建多个实例
可按需求根据类创建任意数量的实例。下面再创建一个名为your_dog 的实例:
#创建多个实例
my_dog = Dog('willie', 6)
your_dog = Dog('lucy', 3)
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")
my_dog.sit()
print("\nYour dog's name is " + your_dog.name.title() + ".")
print("Your dog is " + str(your_dog.age) + " years old.")
your_dog.sit()
#打印结果
My dog's name is Willie.
My dog is 6 years old.
Willie is now sitting.
Your dog's name is Lucy.
Your dog is 3 years old.
Lucy is now sitting.
2 继承
如果你要编写的类是另一个现成类 的特殊版本,可使用继承 。一个类继承 另一个类时,它将自动获得另 一个类的所有属性和方法;原有的类称为父类 ,而新类称为子类 。子 类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。
通过继承创建的新类称为子类或派生类,被继承的类称为基类、父类或超类。
继承语法:
class 派生类名(基类名)
...
在python中继承中的一些特点:
- 1、如果在子类中需要父类的构造方法就需要显示的调用父类的构造方法,或者不重写父类的构造方法。详细说明可查看:python 子类继承父类构造函数说明。
- 2、在调用基类的方法时,需要加上基类的类名前缀,且需要带上 self 参数变量。区别在于类中调用普通函数时并不需要带上 self 参数
- 3、Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
实例:
class Parent:# 定义父类
parentAttr = 100
def __init__(self):
print ("调用父类构造函数")
def parentMethod(self):
print ('调用父类方法')
def setAttr(self, attr):
Parent.parentAttr = attr
def getAttr(self):
print ("父类属性 :", Parent.parentAttr)
class Child(Parent): # 定义子类
def __init__(self):
print ("调用子类构造方法")
def childMethod(self):
print ('调用子类方法')
c = Child() # 实例化子类
c.childMethod() # 调用子类的方法
c.parentMethod() # 调用父类方法
c.setAttr(200) # 再次调用父类的方法 - 设置属性值
c.getAttr() # 再次调用父类的方法 - 获取属性值
#打印结果
调用子类构造方法
调用子类方法
调用父类方法
父类属性 : 200
3 方法重写
如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法:
class Parent: # 定义父类
def myMethod(self):
print ('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self):
print ('调用子类方法')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
#打印结果
调用子类方法
基础重载方法
序号 | 方法, 描述 & 简单的调用 |
---|---|
1 | init ( self [,args…] ) 构造函数 简单的调用方法: obj = className(args) |
2 | del( self ) 析构方法, 删除一个对象 简单的调用方法 : del obj |
3 | repr( self ) 转化为供解释器读取的形式 简单的调用方法 : repr(obj) |
4 | str( self ) 用于将值转化为适于人阅读的形式 简单的调用方法 : str(obj) |
5 | cmp ( self, x ) 对象比较 简单的调用方法 : cmp(obj, x) |
4 类的属性与方法
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的方法
在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用 self.__private_methods
5 特殊符号说明
- foo: 定义的是特殊方法,一般是系统定义名字 ,类似 init() 之类的。
- _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
- __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。
本帖结束,谢谢阅读!
来源:CSDN
作者:WM_40074819
链接:https://blog.csdn.net/qq_40074819/article/details/104371457