美文网首页
python 面向对象

python 面向对象

作者: 周周周__ | 来源:发表于2020-04-11 15:37 被阅读0次

python面向对象:
主要包含的名词有:

  • 类:由class声明的属性和方法的集合,定义了所有对象共有的属性和方法,对象就是类的实例。
  • 类变量:在class中声明的共有变量,在方法外边声明。
  • 方法:类中声明的函数。
  • 实例化:创建类的实例,是类的具体对象。
  • 继承:在py3中声明的对象默认是继承自object,声明的方法class A: == class A(object):
    拥有object内置的所有魔法方法。
>>> class A:
...     pass
>>> dir(A)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', 
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__',
 '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
 '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>>
三大特性--继承、封装、多态
  • 封装:对象就是一个封装了事务的相关的属性和方法、调用类内部的操作,不用关心具体代码实现
  • 多态:每个类有多个实例/对象,每个对象在调用同一个方法的时候,实现的结果是不相同的
  • 继承:子类继承父类的方法,拥有父类的属性的方法。同时可以对父类的方法进行重写,也可以进行添加自己的功能。

继承:

在开始就说明了对象都是继承自object拥有许多内资的魔法函数。

>>> class B:
...     def b(self):
...             pass
...     def c(self):
...             pass
>>> class C(B):
...     pass
>>> dir(C)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', 
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', 
'__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', 
'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 
'b', 'c']

在上边可以看到C 继承自B同时拥有了B的方法 b和c。
在继承的过程中,主要考虑对父类的重写
1、简单重写继承

class M:
    def m1(self):
        return ('this is m1')
    def m2(self):
        return ('this id m2')
class N(M):
    def m1(self):
        return ("this is n1")
n = N()
print(n.m1()) # this is n1

2、super简单继承
这里要明白,add11如果为add那么就是重写了A.add

class A:
    def add(self, x):
        y = x + 1
        print(y)
class B(A):
    def add11(self, x):
        super().add(x)
b = B()
b.add11(2)  # 3
b.add(2) # 3

3、多继承顺序
找到之后就继承,不再执行

class A:
    def add(self, x):
        y = x + 1
        print(y)
class C:
    def add(self, x):
        y = x - 1
        print(y)
class B(C, A):
    def add11(self, x):
        super().add(x)
class D(A, C):
    def add11(self, x):
        super().add(x)
b = B()
b.add11(2)  # 1
d = D()
d.add11(2) # 3

解决问题一:

class Bird:
    def __init__(self):
          self.hungry = True
    def eat(self):
          if self.hungry:
               print 'Ahahahah'
          else:
               print 'No thanks!'
class SongBird(Bird):
     def __init__(self):
          self.sound = 'Squawk'
     def sing(self):
          print self.song()
sb = SongBird()
sb.sing()    # 能正常输出
sb.eat()     # 报错,因为 songgird 中没有 hungry 特性

重写:

class SongBird(Bird):
     def __init__(self):
          super(SongBird,self).__init__()
          self.sound = 'Squawk'
     def sing(self):
          print self.song()

解决问题二:经典的菱形继承案例,BC 继承 A,然后 D 继承 BC,创造一个 D 的对象。

 ---> B ---
A --|          |--> D
     ---> C ---

使用 super() 可以很好地避免构造函数被调用两次。

class A():
    def __init__(self):
        print('enter A')
        print('leave A')
class B(A):
    def __init__(self):
        print('enter B')
        super().__init__()
        print('leave B')
class C(A):
    def __init__(self):
        print('enter C')
        super().__init__()
        print('leave C')
class D(B, C):
    def __init__(self):
        print('enter D')
        super().__init__()
        print('leave D')
d = D()

property、staticmethod、classmethod

  • property:说白了就是把内置的方法修改成像调用属性一样,原来A.a()现在A.a
  • staticmethod:这个就是把函数写在类内部,其实和它没关系,调用的方法就是A.a()或者A.a()
  • classmethod:传入cls,其实就是类本身,该函数只能访问到类的数据属性,不能获取实例的数据属性
    类方法,实例也可以调用,但是并没有什么用,违反了初衷:类方法就是专门供类使用
class D:
    def __init__(self, name):
        self.name = name
    def d(self):
        return self.name
    @property
    def f(self):
        return self.name
    @staticmethod
    def g():
        return 1
    @classmethod
    def h(cls):
        return cls
d = D(1)
print(d.d())
print(d.f)
print(d.name)
print(d.g())
print(D.h())

相关文章

网友评论

      本文标题:python 面向对象

      本文链接:https://www.haomeiwen.com/subject/brvymhtx.html