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 …

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值