Python_面向对象
类的定义
Python使用class关键字来定义类,class关键字之后是一个空格,接下来是类的名字,如果派生(继承)自其他基类的话,则需要把所有基类放到一对圆括号中并使用逗号分隔,然后是一个冒号,最后换行并定义类的内部实现。类的首字母一般要大写
语法格式 :
class 类名(object):
定义构造方法,实例化时初始化类的属性
def 两个下划线+init+两个下划线(self, 属性):
self.属性 = 属性定义类的方法
def 方法名(self):
方法体
创建实例/对象
对象名 = 类名(参数)
调用方法
对象名.方法名()
添加属性或修改属性
对象名.属性名 = 属性
删除属性
del 对象名.属性名
示例
class Student(object):
# 定义构造方法
def __init__(self, name, score):
self.name = name
self.score = score
# 定义方法
def printInfo(self):
print("%s : %d" % (self.name, self.score))
# 创建两个个对象
stu1 = Student("小白", 99)
stu2 = Student("小安", 80)
# 调用方法
stu1.printInfo()
# 添加属性;在stu1对象中添加的新属性,只在stu1中生效,在别的对象中不能使用
stu1.age = 18
print(stu1.age)
# print(stu2.age)
# 修改属性;#在stu1中修改的属性同样只在stu1中生效,与别的对象无关
stu1.name = "小黑"
stu1.printInfo()#>>>小黑 : 99
stu2.printInfo()#>>>小安 : 80
# 删除属性;在stu1中删除的属性同样只在stu1中生效,与别的对象无关
del stu1.name
# print(stu1.name)
print(stu2.name)
❤️ 注意 __init__方法的第一个参数永远是self,表示创建的实例本身(类似Java中的this),因此,在__init__方法内部,就可以把各种属性绑定到self,
因为self就指向创建的实例本身;某个对象调用其方法时,Python解析器会把这个对象名作为第一个参数传递给self,所以开发者只需要传递后面的参数即可。
有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解析器自己会把实例对象名传进去。
在类的定义中,__init__并不是必需的。只有当需要区分由该类创建的不同对象时,才需要指定__init__方法
数据成员-实例变量与类变量
数据成员可以大致分为两类:属于对象的数据成员(实例变量)和属于类的数据成员(类变量);实例变量主要指在构造函数__ init __()中定义的(当然也可以在其他方法中定义),定义和使用时必须以self作为前缀(这一点是必须的),同一个类的不同对象(实例)之间的数据对象成员之间互不影响;属于类的数据对象是该类所有对象共享的,不属于任何一个对象,在定义类时这类数据成员不在任何一个成员方法的定义中。在主程序中或类的外部,实例变量成员属于实例,只能通过对象名访问;而类变量成员属于类,可以通过类名或对象名访问。另外,在Python中可以动态地为类和对象增加成员
class Student(object):
name = “UserPython” #类变量–属于类的数据成员
age = 18
def __init __ (self, age):
self.age = age #实例变量–属于对象的数据成员
def printInfo(self):
print("%s" % self.age)
不用创建实例即可直接访问类变量
print(Student.name)>>>UserPython
可以通过“对象名.类变量”访问类变量;优先访问实例变量,如果实例变量没有再访问类变量
stu1 = Student(19)
print(stu1.name, stu1.age)>>>UserPython 19
通过stu1修改类变量,其实并不是真的修改了类变量,而是在stu1中新创建了一个name实例变量,这个与类变量无关,与其他实例对象无关
stu1.name = “HHHH”
print(stu1.name, Student.name)>>>HHHH UserPython
stu2 = Student(20)
print(stu2.name)
print(Student.name)>>>UserPython,因为stu2中没有添加实例变量name,所以返回的是类变量name
>>>UserPython
直接修改类变量
Student.name = “UUUU”
print(stu1.name)
print(Student.name)>>>HHHH 因为优先访问实例变量所以还是返回“HHHH”
>>>UUUU
私有属性与私有方法
在定义类的成员时,如果成员以两个下划线(__)开头,则表示是私有成员,但是Python并有对私有成员提供严格的访问保护机制。Python提供了一种特殊方式“对象名._类名 __XXX”可以访问私有成员,但这会破坏类的封装性。
class Student(object):
def init(self, name, age):
self.__name = name #在属性的前面加上两个下划线即可让该属性变成私有属性
self.age = age
def __ del __(self):
pass
如果想获取私有属性可以定义一个方法来访问私有属性,因为同一个类中,私有属性是可见的,只是在类外部私有属性不可访问
def getName(self):
print(self.__name)
同样的想修改私有属性,可以通过定义一个方法来修改
def setName(self, name):
self.__name = name
def printInfo(self):
print("%s : %d" % (self.__name, self.age))
在方法的前面加上两个下划线即可让该方法变成私有方法,外部无法访问
def __showInfo(self):
print("%s : %d" % (self.__name, self.age))
stu1 = Student(“小白”, 18)
stu1.printInfo()>>>小白 : 18
print(stu1.__name) #不能再访问私有属性
print(stu1.age) #非私有属性依旧可以访问
stu1.getName() #可以通过定义一个方法访问私有属性
stu1.setName(“小小白”)
stu1.printInfo()>>>小小白 : 18
方法
析构方法
import time
class Test(object):
def __init__(self, name):
self.name = name
def __del__(self):
print("%s已经被kill了" % self.name)#此句可不写,默认为空语句即可
def printInfo(self):
print("你的名字为:%s" % self.name)
test1 = Test("小白")
test1.printInfo()
# del test1 #手动删除一个对象时,是即时调用__del__()方法删除该对象,而不是等程序结束再删除
test2 = Test("小黑")
test2.printInfo()
# 模拟程序还有其他代码
for t in range(100):
print(t)
time.sleep(0.1)
❤️ 如果程序在运行过程中,没有手动调用del来删除一个对象时,而Python解析器检测到该对象又没有任何用处了,那么解析器就会在程序运行结束时,自动调用__del__()方法把这个对象kill掉,为什么要等到程序结束才kill呢?因为解析器还要检查后面的程序是否还有用到该对象嘛!
静态方法
静态方法:实际上跟类没什么关系,只是名义上归类管理可以通过对象名调用静态方法,实际上在静态方法里访问不了类或实例中的任何属性
class People(object):
def __ init__(self, name):
self.name = name
@staticmethod
def talk(self):
print("%s is talking" % self.name)
people = People(“UserPython”)
people.talk(people)
>>>UserPython is talking
类方法
只能访问类变量,不能访问实例变量
class People(object):
name = “UserH”
def __ init__(self, name):
self.name = name
print(“实例变量self.name>>>%s” % self.name)
@classmethod
def talk(self):
print("%s is talking" % self.name)
people = People(“UserPython”)
people.talk()>>>实例变量self.name==>UserPython
>>>UserH is talking
属性方法
把一个方法变成一个静态属性
class People(object):
def __ init__(self, name):
self.name = name
self.__friend = None
属性方法:把一个方法变成一个静态属性
@property
def talk(self):
print("%s is talking with %s" % (self.name, self.__friend))
修改属性方法
@talk.setter
def talk(self, friend):
print("%s is talking with %s" % (self.name, friend))
self.__friend = friend
删除属性方法
@talk.deleter
def talk(self):
del self.__friend
people = People(“UserPython”)
调用的是@property的talk()方法
people.talk>>>UserPython is talking with None
给属性方法赋值,调用的是@talk.setter的talk()方法
people.talk = “UserH”>>>UserPython is talking with UserH
people.talk
>>>UserPython is talking with UserH
删除属性方法
del people.talk
people.talk
>>>AttributeError: ‘People’ object has no attribute ‘_People__friend’ (说明删除成功)
继承
继承可以让子类全部获取父类的功能,相当于在子类中复制粘贴了父类的代码,也可以重写父类不合适的代码
父类class People(object):
构造方法
def __ init__(self, name, age):
self.name = name
self.age = age
def sayHello(self):
print(“你好!我是一个People”)
子类继承父类class Student(People):
重构父类构造方法
def __ init__(self, name, age, score):
super(Student, self).__ init__(name, age) #方法一(建议使用)
People.__init __(self, name, age) #方法二
self.score = score
重写父类方法
def sayHello(self):
super(Student, self).sayHello() #保留父类方法中的内容,继承父类的方法,方法一
#People.sayHello(self) 方法二
print(“你好!我是一个学生”) #重写的内容或添加的内容
stu1 = Student(“UserPython”, 18, 23)
多继承
父类class People(object):
def sayHello(self):
print(“你好!我是一个People”)
class Man(object):
def showMe(self):
print(“你好!我是一个男人”)
子类多继承class Student(People, Man): #多继承
pass
stu1 = Student()
stu1.sayHello()
stu1.showMe()
>>>你好!我是一个People
>>>你好!我是一个男人
多继承顺序
class A(object):
def __ init__(self):
print(“AAAAA”)
class B(A):
# def __ init__(self):
# print(“BBBBB”)
pass
class C(A):
def __ init__(self):
print(“CCCCC”)
pass
class D(B, C):
# def __ init__(self):
# print(“DDDDD”)
pass
test = D()
>>>CCCCC
从上面可以看出Python3多继承的顺序为广度优先(即D继承B后,如果发现B中没有所需内容再从继承C中查找,而不是发现B中没有所需内容直接到A中查找,当C中也没有时,才到A中查找),Python2为深度优先继承
多态
class Animal(object):
def __ init__(self, name):
self.name = name
def talk(self):
pass
python中多态写法 def animal_talk(obj):
obj.talk()
class Cat(Animal):
def talk(self):
print("%s : miao miao miao …" % self.name)
class Dog(Animal):
def talk(self):
print("%s : wang wang wang …" % self.name)
dog = Dog(“小狗”)
Animal.animal_talk(dog) #等价于dog.talk()
cat = Cat(“小猫”)
Animal.animal_talk(cat) #等价于cat.talk()
>>>小狗 : wang wang wang …
>>>小猫 : miao miao miao …
下一篇: python面向对象
推荐阅读
-
Python面向对象程序设计OOP深入分析【构造函数,组合类,工具类等】
-
Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】
-
Python面向对象类编写细节分析【类,方法,继承,超类,接口等】
-
用DOM实现文章采集--通过jquery语法式的方法采集指定对象的文本
-
Axure RP 8怎么制作锁定对象或隐藏对象?
-
javascript 时间显示代码集合(Date对象)
-
PHP 面向对象程序设计(oop)学习笔记(一) - 抽象类、对象接口、instanceof 和契约式编程
-
PHP 面向对象程序设计(oop)学习笔记 (四) - 异常处理类Exception
-
PHP 面向对象程序设计(oop)学习笔记(三) - 单例模式和工厂模式
-
PHP 面向对象程序设计(oop)学习笔记 (二) - 静态变量的属性和方法及延迟绑定