简单解释Python的类和对象

管理员 2019-12-18 PM 92℃ 0条

前言:

对象是模拟真实世界,把数据和程序进行封装 。

对象 = 属性+ 方法

我们需要用类来创造一个对象,就像我们要用图纸来造房子一样。在Python中函数名是以小写字母开头 ,类名是以大写字母开头。

0x00:面向对象(Object Oriented)我们一般称为OO,OO的特征有

1.封装

就像我们对列表的操作一样,很多方法已经封装好了,我们只需要调用自己需要的方法的名字就好了

>>> list1 = [2,1,7,4,3]
>>> list1.sort()
>>> list1
[1, 2, 3, 4, 7]
>>> list1.append(9)
>>> list1
[1, 2, 3, 4, 7, 9]
>>>

2.继承

继承是子类自动共享父类之间数据和 方法的机制

>>> class Mylist(list):
	pass
 
>>> list2 = Mylist()
>>> list2.append(5)
>>> list2.append(6)
>>> list2
[5, 6]
>>> list2.append(3)
>>> list2.sort()
>>> list2
[3, 5, 6]
>>> 

我们创建的类可以继承列表的很多属性

3.多态

多态就是不同对象对同一方法响应不同的行动


>>> class A:
	def fun(self):
		print('我是0verflow')
 
		
>>> class B:
	def  fun(self):
		print('我是XX')
 
		
>>> a = A()
>>> b = B()
>>> a.fun()
我是0verflow
>>> b.fun()
我是XX
>>>

我们上面的程序用到了self,但是它 什么东西我们并没有解释,其实它就相当于一个序号

>>> class Ball:
	def setname(self,name):
		self.name = name
	def kick(self):
		print('谁踢我%s。。。。。'  % self.name)
 
		
>>> a = Ball()
>>> a.setname('A')
>>> b = Ball()
>>> b.setname('B')
>>> c= Ball()
>>> c.setname('C')

0x01:python的 魔法方法 __init__(self)(构造方法):

__init__(self ,  param1, param2...)


>>> class Ball:
	def __init__(self,name):
		self.name = name
	def kick(self):
		print('我叫%s' % self.name)
 
		
>>> b = Ball('0verflow')
>>> b.kick()
我叫0verflow
>>> a = Ball()
Traceback (most recent call last):
  File "<pyshell#54>", line 1, in <module>
    a = Ball()
TypeError: __init__() missing 1 required positional argument: 'name'
>>>

因为我们设置了默认参数如果不传入参数就会报错  。

0x02:公有和私有

公有和私有的意义这里我就不解释了,就是字面意思

默认来说对象的属性和方法都是公有的,为了实现私有Python内部给出了一个name mangling(名字改编,名字重整)的机制

在python中定义私有变量只需要在变量名或函数名前加上‘’__‘’两个下划线,Python所谓的私有只是意义上的,为什么这么说看下面的代码大家就明白了。


>>> class Person:
	name =  '0verflow'
 
	
>>> p = Person()
>>> p.name
'0verflow'
>>> class Preson:
	__name = '0verflow'
 
	
>>> p = Person()
>>> p.__name
Traceback (most recent call last):
  File "<pyshell#65>", line 1, in <module>
    p.__name
AttributeError: 'Person' object has no attribute '__name'
>>>

针对上面的代码想打印私有还是可以的,不过要多写一个函数:


>>> class Preson:
	__name = '0verflow'
	def getname(self):
		return self.__name
 
	
>>> p = Preson()
>>> p.getname()
'0verflow'
>>>

其实我们也可以通过另一种方式:_类名__变量名


>>> class Preson:
	__name = '0verflow'
	def getname(self):
		return self.__name
 
>>> p._Preson__name
'0verflow'
>>>

这里我们在来说一下继承

被继承者我们 称为基类或父类,继承者我们称为子类,子类可以继承父类的属性和方法。

>>> class Parent:
	def hello(self):
		print('正在调用父类的方法')
 
		
>>> class Child(Parent):
	pass
 
>>> p = Parent()
>>> p.hello()
正在调用父类的方法
>>> c = Child()
>>> c.hello()
正在调用父类的方法
>>> class Child(Parent):
	def hello(self):
		print('正在调用子类的方法')
 
		
>>> c = Child()
>>> c.hello()
正在调用子类的方法
>>> p.hello()
正在调用父类的方法
>>>

在举一个例子说明一下:


import random as r
 
 
class Fish:
      def __init__(self):
            self.x = r.randint(0,10)
            self.y = r.randint(0,10)
            
      def move(self):
           self.x -= 1
           print('我的位置是:',self.x ,self.y)
 
class Goldfish(Fish):
      pass
class Carp(Fish):
      pass
class Shark(Fish):
      def __init__(self):
            self.hungry = True
 
      def eat(self):
            if self.hungry:
                  print('饿了,要进食')
                  self.hungry = False
            else:
                  print('吃饱了')

从上面的例子运行的结果可以看出,我们在让shark移动的时候莫名其妙的报错了,原因是因为我们从新定义了__init__()所以覆盖掉了父类的方法和属性。针对 这个问题有两种解决的办法:

1.使用未绑定的父类

看一下运行的结果:


>>> fish = Fish()
>>> fish.move()
我的位置是: 2 8
>>> goldfish  = Goldfish()
>>> goldfish.move()
我的位置是: 9 0
>>> shark = Shark()
>>> shark.eat()
饿了,要进食
>>> shark.eat()
吃饱了
>>> shark.move()
Traceback (most recent call last):
  File "<pyshell#101>", line 1, in <module>
    shark.move()
  File "D:\Python\test\test.py", line 10, in move
    self.x -= 1
AttributeError: 'Shark' object has no attribute 'x'
>>>

import random as r
 
 
class Fish:
      def __init__(self):
            self.x = r.randint(0,10)
            self.y = r.randint(0,10)
            
      def move(self):
           self.x -= 1
           print('我的位置是:',self.x ,self.y)
 
class Goldfish(Fish):
      pass
class Carp(Fish):
      pass
class Shark(Fish):
      def __init__(self):
            Fish.__init__(self)
            self.hungry = True
 
      def eat(self):
            if self.hungry:
                  print('饿了,要进食')
                  self.hungry = False
            else:

我们增加了一行代码 :Fish.__init__(self)这行代码中的self已经不是父类的self了,而是子类的self

运行的结果:


>>> shark = Shark()
>>> shark.move()
我的位置是: -1 3
>>>

2、super()


import random as r
 
 
class Fish:
      def __init__(self):
            self.x = r.randint(0,10)
            self.y = r.randint(0,10)
            
      def move(self):
           self.x -= 1
           print('我的位置是:',self.x ,self.y)
 
class Goldfish(Fish):
      pass
class Carp(Fish):
      pass
class Shark(Fish):
      def __init__(self):
            super().__init__()
            self.hungry = True
 
      def eat(self):
            if self.hungry:
                  print('饿了,要进食')
                  self.hungry = False
            else:
                  print('吃饱了')

这种方法是将上一种方法的那一条添加的语句改为: super().__init__()

看一下运行的结果:


>>> shark = Shark()
>>> shark.move()
我的位置是: -1 5
>>> 

第二种方法比较简单便捷,所以我们一般情况会用第二种方法。

多重继承:一个子类可以继承多个父类的属性和方法


>>> class Base1:
	def fool1(self):
		print('我是fool1')
 
		
>>> class Base2:
	def fool2(self):
		print('我是fool2')
 
		
>>> class C(Base1,Base2):
	pass
>>> c  = C()
>>> c.fool1()
我是fool1
>>> c.fool2()
我是fool2
>>> 

多继承很容易导致一些不可知的错误,所以一般情况下我们是不使用的。

标签: none

非特殊说明,本博所有文章均为博主原创。

评论啦~