Jay jay
文章28
标签2
分类0
python学习三面向对象的程序设计

python学习三面向对象的程序设计

面向对象程序设计

两种程序设计方式:

  • 面向过程程序设计(POP):把计算机程序视为一系列集合即一组函数按事先顺序执行,函数为基本单位。
  • 面向对象程序设计(OOP):把计算机程序视为一组对象的集合,每个对象可以接受其他对象发送的消息,程序的执行指的是消息在各个对象之间的传递,对象是基本单位。

python支持POP、OOP。

OOP:基本思想将数据以及对数据的操作封装在一起组成一个相互依存不可分割的整体,及对象。对相同,类型的对象进行分类、抽象后得出共同特征而形成类。基本概念包括对象、类、消息、封装、继承和多态

对象是要研究的任何事物,类是一组具有相同特征和相同操作对象的定义,一个类所包含的数据和方法描述一组对象的共同特征和行为。不同类之间可以有继承关联依赖等关系。

消息:消息是一个对象要求另一个对象实施某项操作的请求。

类的定义:

类是一种类型,对象是该类型的一个变量,类是抽象的,一般不占用内存空间,对象是具体的,创建对象时系统会为其分配相应的内存空间。

格式:

class 类名:
"""类说明"""
类体 包含数据成员(成员)成员方法(行为)

对象创建和使用

格式:

对象名=类名([参数列表])

使用:

对象.成员 对象.方法()

类的成员:

成员类型:

按照访问权限分类:

  1. 公有成员:(类内外均可访问)

    不以下划线开头

  2. 私有成员:

    以单下划线或双下划线开头

    • 单下划线开头的私有成员:类和派生类可以访问这些成员,在类外不建议直接访问
    • 双下划线开头的私有成员(但不能以两个或更多下划线结束):只有类自己可以访问,派生类不能访问

按照属于类还是属于对象分类:

  1. 类成员:定义在类体中且在所有方法外的成员为类成员,类成员属于类本身,一般通过类名调用,不建议使用对象名调用。
  2. 实例成员:在类的方法中定义的成员为实例成员。实例成员只能被对象调用,实例成员一般在构造方法”_init_()”中创建,或在其他方法中创建

对类成员访问:

  1. 公有的类成员:在类的方法中通”类名.类成员”或”self.类成员”访问,在类外通过”类名.类成员”或“对象名.类成员”访问。

  2. 公有的实例成员:在类的方法中通过“self.实例成员”访问,在类外通过“对象名.实例成员”访问

  3. 私有的类成员:在类的方法中通过”类名.类成员“或”self.类成员”访问。在类外面不能直接访问

  4. 私有的实力成员:在类方法中通过“self.实力成员”访问,在类外不能直接访问。

注意:

  1. 当用对象名调用类成员时“对象名.类成员名”只是“类.类成员”的一份拷贝,修改“对象名.类成员名”不会修改“类.类成员”。
  2. 当类成员和实例成员名同名时,在类的方法中和外面,“类名.类成员”调用的是同名的类成员,“self.实例成员”(在类方法中)或“对象名.实例成员”(在类的外面)调用的是同名的实例成员。
  3. 定义在类的方法中,且不以self为前缀的变量是该方法的局部变量,不能在方法外使用。

例子:定义一个Women类

class Woman:
def __init__(self,name,sex,age):
self.name=name
self._sex=sex
self.__age=age
def getAge(self):
return self.__age

if __name__ == '__main__':
w=Woman("小贾","Female",18)
print("姓名:%s,性别:%s,年龄:%d."%(w.name,w._sex,w.getAge()))

结果

例2:类成员和实例成员的创建和使用

class Student:
chinese=142 #类成员
maths=1
english=141
#定义构造方法
def __init__(self,name):
self.name=name #实例成员

if __name__ == '__main__':
s1=Student("加魔")
print("{}的语文成绩{}".format(s1.name,str(Student.chinese)))
print("{}的数学成绩{}".format(s1.name, str(Student.maths)))
print("{}的英语成绩{}".format(s1.name, str(Student.english)))

结果

内置成员:

所有的类(无论是系统内置的类还是自定义的类)都有一组特殊的成员,其前后各有两个下划线时类的内置成员:

  1. __name__:类的名字,用字符串表示
  2. __doc__:类的文档字符串
  3. __bases__:由所有父类组成的元组
  4. __dict__:由类的成员组成的字典
  5. __module__:类所属模块

查看异常类Exception的内置成员:

print("类的名字:",Exception.__name__)
print("类的父类:",Exception.__bases__)
print("类的文档:",Exception.__doc__)
print("类的成员:",Exception.__dict__)
print("类所属模块:",Exception.__module__)

结果

类的方法:

  1. 公有方法:公有方法的名字不以下划线开头,可以在类的外面通过类名或对象名调用

  2. 私有方法:私有方法以两个或更多下划线开头,可以在类的方法中通过self调用,不能在类的外面直接调用。

  3. 静态方法和类方法:

    • 静态方法和类方法成员可以通过类名和对象名调用,但不能直接访问属于对象的成员只能访问属于类的成员,不属于任何对象

    • 静态方法使用装饰器@staticmethod声明,类方法使用装饰器@classmethod声明

  4. 抽象方法:抽象方法一般定义在抽象类中并要求派生类对抽象方法进行实现

使用类方法:

#使用类方法
class A(object): #派生自object类
def function_p(self):
print("在公有方法中调用:",self.__function()) #调用私有方法
return "公有方法 'function_p'"
def __function(self):
return "私有方法 '__function'"
@classmethod
def function_c(cls):
return "类方法 'function_c'"
@staticmethod
def function_s():
return "静态方法 'function_s'"
if __name__ == '__main__':
a1 = A()
print("对象调用:" + a1.function_p())
print("对象调用:" + a1.function_c())
print("对象调用:" + a1.function_s())
print("对象调用:" + A.function_p(a1)) #传递对象a1作为参数
print("对象调用:" + A.function_c())
print("对象调用:" + A.function_s())

结果

属性:

  • 一种特殊形式的方法,结合了成员和方法的各自优点,既可以通过属性访问类中的成员,也可以在访问前对用户为成员提供数据的合法性进行检测,还可以设置成员的访问机制

  • 属性通常包括get()方法和se()方法。前者用于获取成员的值,后者用于设置成员的值

  • 也可以包含其他方法如删除方法del()

例:使用属性访问并检查私有成员值的合法性:

#使用属性访问并检查私有成员值的合法性:
class Circle:
def set(self,radius):
if radius>=0:
self.__radius=radius
print("圆的面积为:{0}.".format(3.14*self.__radius**2))
else:
print("半径 %f 不在规定范围内(>=0),请重新设置!"%radius)
def get(self):
return self.__radius

if __name__ == '__main__':
c=Circle()
c.set(2.5)
c.set(-2.5)

结果

使用装饰器@property设置类的属性访问方式

#使用装饰器@property设置类的属性访问方式
class Woman():
def __init__(self,birth):
self.__birth=birth
@property #设置属性可读
def salary(self):
return self.__salary
@salary.setter #设置属性为可写
def salary(self,salary):
self.__salary=salary
@property #设置属性为只读8
def birth(self):
return self.__birth
if __name__ == '__main__':
w1=Woman("1992.06.06")
w1.salary=10800.00
print("您的出生日期%s,薪水:%.2f元"%(w1.birth,w1.salary))

结果

使用属性访问私有成员:

#使用属性访问私有成员
class Test():
def __get(self):
return self.__value
def __set(self,value):
self.__value=value
def __del(self):
del self.__value
value=property(__get,__set,__del)
if __name__ == '__main__':
t=Test()
t.value=100 #写成员
print("value=%d." %t.value) #读成员
del t.value
print("value=%d." %t.value)

结果

特殊方法:

  • 在python中,类有大量的特殊方法,其中比较常见的是构造方法__init__()和析构方法__del__()

  • 构造方法__init__()用来为类中的成员设置初始值或进行必要的初始化工作,在类实例化时被自动调用和执行

  • 析构方法:__del__()一般用来释放对象占用的资源,在删除对象和回收对象空间时被自动调用和执行

构造方法和析构方法的使用:

class Rectangle(object):
def __init__(self,w,h):
self.w=w
self.h=h
print('执行构造方法')
#定义求面积
def getArea(self):
return self.w*self.h
#定义析构方法
def __del__(self):
print('执行析构方法')
if __name__ == '__main__':
rect =Rectangle(3,4) #创建对象,调用构造方法__init__()
print("面积为:",rect.getArea())
del rect #删除对象,调用析构方法__del__()

结果

类的继承:

  • 继承类称为派生类或子类,被继承类成为父类或基类

  • 在python中,派生类可以继承一个父类(单继承)或多个父类(多继承)。

  • 派生类可以继承父类的成员和方法,也可以定义自己的成员方法

  • 如果父类方法不能满足要求,派生类也可以重写父类方法

  • 当派生类继承多个父类时,多个父类之间用逗号隔开

  • 创建派生类的一般格式为:

    class 派生类(父类1,父类2,。。。)
    类体

类的继承

#类的继承:
class People:
def __init__(self,n,a):
self.name=n
self.age=a

#定义公有方法
def speak(self):
print("我是{},今年{}岁".format(self.name,self.age))
class Student(People):
def __init__(self,n,a,g):
People.__init__(self, n, a)#调用父类构造方法
self.grade=g
#重写父类方法
def speak(self):
print("我是{},今年{}岁,今年{}年级".format(self.name, self.age,self.grade))
if __name__ == '__main__':
s=Student('贾程林',40,2)
s.speak();#调用student类中的speak方法
super(Student,s).speak()#调用父类people的speak方法

结果

类的多继承:

#类的继承:
class People:
def __init__(self,n,a):
self.name=n
self.age=a

#定义公有方法
def speak(self):
print("我是{},今年{}岁".format(self.name,self.age))
#类的多继承
class Speaker():
def __init__(self,n,t):
self.name=n
self.topic=t
def speak(self):
print("我是{},是一名科学家,今天我演讲的主题是{}".format(self.name, self.topic))

#定义科学家类继承于people和seapker
class Scientist(Speaker,People):
def __init__(self,n,a,t):
People.__init__(self,n,a)
Speaker.__init__(self,n,t)
if __name__ == '__main__':
Hawkin=Scientist('霍金',50,"时间简史")
Hawkin.speak()#调用继承时排在前面的Speaker类的speak()方法

结果

类的多态:

  • 多态一般指的是父类的一个方法在不同的派生类对象中具有不同的表现和行为

  • 派生类在继承了父类的行为和属性之后还可能增加某些特性的行为和属性,也可能会对继承父类的行为进行一定的改变,这些都是多态的表现

    #类的多态:
    class Animal():
    def getInfo(self):
    return "I am an Animal"

    class Lion(Animal):
    def getInfo(self):
    return "I am a Lion"

    class Tiger(Animal):
    def getInfo(self):
    return "I am a Tiger"
    class Leopard(Animal):
    def getInfo(self):
    return "I am a Leopard"
    if __name__ == '__main__':
    objectList=[item()for item in (Animal,Lion,Tiger,Leopard)]
    for object in objectList:
    print(object.getInfo())

    结果

抽象类和抽象方法:

  • 抽象类往往用来表征对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同但本质上相同的概念抽象
  • 抽象类的特点:抽象类中通常包含抽象方法(没有实现功能),该类不能被实例化,只能被继承,且派生类必须实现抽象类中的抽象方法
  • Python中一般使用抽象基类(Abstract Base Class,ABC)来实现抽象类
  • ABC主要定义了基本类和最基本的抽象方法,可以派生类定义公有API,不需要具体实现,相当Java的接口或抽象类
#定义抽象类:
import abc
class People1(metaclass=abc.ABCMeta):
#定义抽象方法
@abc.abstractmethod
def working(self):
pass
class Chinese(People1):
def working(self):
print("中国人都在勤奋的工作")

if __name__ == '__main__':
c1=Chinese()
c1.working()

结果

结束

本文作者:Jay jay
本文链接:https://yyj-xx.github.io/2021/10/08/python%E5%AD%A6%E4%B9%A0%E4%B8%89%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%9A%84%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可