鱼C论坛

 找回密码
 立即注册
查看: 2116|回复: 0

[技术交流] 第十章:类和对象(38-40课时)

[复制链接]
发表于 2017-8-18 11:03:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 向西而笑 于 2017-8-18 11:21 编辑

           38课时:继承
继承的写法和使用方法
只要在子类名加上括号和父类的名字就表示继承了父类(class子类名(父类名):)。被继承的类称作基类、父类、超类,继承的类称作子类。子类继承了父类所有的属性和方法。
例子:
>>> 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()
正在调用父类的方法..



子类和父类中成员重名问题
如果子类的方法和父类的重名了,一般是覆盖掉父类的方法。但我希望既能继承父类的方法也能保留子类的方法,python中有两个解决方法:调用未绑定的父类方法和使用super方法,前者弊端大不推荐,super()方法非常的强大,就用这个方法。
举例:
>>> class A:
        def __init__(self):
                print('进入A...')
                print('离开A...')
>>> class B(A):
        def __init__(self):
                print('进入B...')
                super().__init__()
                print('离开B...')
>>> b = B()
进入B...
进入A...
离开A...
离开B...


多重继承
在python中可以一个子类可以继承多个父类。写法是:class 子类(父类1,父类2...)。多重继承容易产生问题,要慎重使用
>>> class A:
        def __init__(self):
                print('进入A...')
                print('离开A...')
>>> class B(A):
        def __init__(self):
                print('进入B...')
                super().__init__()
                print('离开B...')
>>> class C(A):
        def __init__(self):
                print('进入C...')
                super().__init__()
                print('离开C...')
>>> class D(B,C):
        def __int__(self):
                print('进入D...')
                super().__init__()
                print('离开D...')
>>> d = D()
进入B...
进入C...
进入A...
离开A...
离开C...
离开B...



          39课时:拾遗
类的组合
类之间的继承属于纵向关系,除了纵向关系还有横向关系,即类组合。但类之间有派生关系用继承更好,但我只想要在类中加入其他类的功能就用组合。通过类的实例化来调用类。例如:
>>> class Turtle:
        def __init__(self,x):
                self.x = x
>>> class Fish:
        def __init__(self,y):
                self.y = y
>>> class Pool:
        def __init__(self,x,y):
                self.turtle = Turtle(x)
                self.fish = Fish(y)
        def printnum(self):
                print('池塘内的乌龟有%d只,小鱼有%d条!'%(self.turtle.x,self.fish.y))
>>> pool = Pool(10,100)
>>> pool.printnum()
池塘内的乌龟有10只,小鱼有100条!



属性和方法重名问题
如果属性和方法重名了,那么属性会覆盖掉方法。。
例子:
>>> class Example:
        def fun(self):
                print('我成功显示了')
>>> case = Example()
>>> case.fun()
我成功显示了
>>> case.fun = '我变成属性了'
>>> case.fun()
Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    case.fun()
TypeError: 'str' object is not callable
>>> case.fun
'我变成属性了'
解决方法:1、不要试图在类里面定义出所有想到的属性和方法应该利用继承和组合机制来扩展。  2、用不同的词性命名属性名用名词,方法名用动词。例如定义一个矩形类,定义长的属性用’len’,定义求面积的方法用’getArea’这样的词

类定义、类对象、类实例化对象
定义完一个类后,类就成为了类对象,通过类实例化后的对象就成为了类实例化对象。类定义的属性和方法是静态的,类实例化后的属性和方法是动态的。
例子:
>>> class X:
        count = 0      #开始定义count属性等于0

>>> a = X()
>>> b =X()
>>> a.count
0
>>> b.count
0

>>> a.count += 10  #这里改变实例化对象a的count属性
>>> a.count    
10
>>> X.count     #结果显示X类的count属性并没有收到影响
0
>>> b.count     #实例化对象b也没收到影响
0

>>> X.count += 100  #这里改变X类的count属性
>>> X.count
100
>>> b.count      #b的count属性跟着改变了
100
>>> a.count      #然而a的count属性却还是10
10
如果类属性和方法改变,实例化对象会跟着改变

        40课时:一些相关的BIF
这节课讲的是有关类的一些BIF
issubclass(clas,classinfo):如果第一个参数class是第二个参数classinfo的子类则返回True。注意:1、一个类被认为是自身的子类。2、clasinfo可以是有类对象组成的元组,只要class是其中任何一个候选类的子类就返回True。
>>> class X:
        pass
>>> class A(X):
        pass
>>> issubclass(A,A)  #自己是自己的子类
True
>>> issubclass(A,X)
True
>>> issubclass(X,object)  #object是所有类的基类
True



isinstance(object,classinfo):用于检查一个对象是否属于某种类,是返回True,不是返回False。这个是之前学了的函数,也可以用于检查一个对象是不是某个类的实例对象,class是一个类实例对象classinfo同样可以是由类组成的元组。
>>> class X:
        pass
>>> a = X()
>>> class Z:
        pass
>>> isinstance(a,X)
True
>>> isinstance(a,Z)
False



hasattr(object,name):测试一个对象是否有指定的属性。name必须是字符串的形式。举例:
>>> class X:
        def __init__(self,a=0):
                self.a = a
>>> x = X()
>>> hasattr(x,'a')
True



getattr(object,name[,default]):
返回对象指定属性的值,name也是要求是字符串的形式。如果设置了默认值default,指定属性不存在时返回default,否则抛出异常。
>>> class X:
        a = 10
>>> x = X()
>>> getattr(x,'a')
10
>>> getattr(x,'b')
Traceback (most recent call last):
  File "<pyshell#20>", line 1, in <module>
    getattr(x,'b')
AttributeError: 'X' object has no attribute 'b'
>>> getattr(x,'b','这个属性不存在!')
'这个属性不存在!'


setattr(object,name,value):为对象指定属性设置值,name要求是字符串形式,如果指定属性不存在则新建一个属性。
>>> class Z:
        x = 1
>>> z = Z()
>>> setattr(z,'x',2)
>>> getattr(z,'x')
2
>>> setattr(z,'y',10)
>>> getattr(z,'y')
10



delattr(object,name):与setattr()作用相反,删除对象的指定属性,如果指定属性不存在则抛出attribute异常。

property(fget=None,fset=None,fdel=None,doc=None):用property()函数使得在访问属性值调用第一个参数,设置属性调用第二个参数,删除属性调用第三个参数,三个参数都是方法。举例:
>>> class Case:
        def __init__(self,size):
                self.size = size
        def getSize(self):
                return self.size
        def setSize(self,value):
                self.size = value
        def delSize(self):
                del self.size
        z = property(getSize,setSize,delSize)
>>> c =Case(10)
>>> c.z
10
>>> c.__dict__
{'size': 10}
>>> c.z = 100
>>> c.z
100
>>> del c.z
>>> c.z
Traceback (most recent call last):
  File "<pyshell#36>", line 1, in <module>
    c.z
  File "<pyshell#28>", line 5, in getSize
    return self.size
AttributeError: 'Case' object has no attribute 'size'
>>> c.__dict__
{}


这个property()到底有什么用呢?用上例来说明的话,如果对size属性修改比如重命名或者设置成私有变量,那么实例化对象调用这个属性就会出错,要想正确调用就要相应地修改代码,太麻烦了;如果运用了proper,不管在类定义里如何改变size,实例对象还是只要调用z就可以了。以上就是我的浅薄理解,如有不对,请多赐教,谢谢。


评分

参与人数 1鱼币 +6 收起 理由
小甲鱼 + 6

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 10:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表