13、面向对象进阶

1、 对象的继承

 类可以继承一个父类、也可以继承多个父类。其中,继承前者叫单继承,后者叫多继承。

单继承:class 子类名(父类)
多继承:class 子类名(父类1,父类2,…)

示例1:完全继承

class Rectangle:
    def __init__(self,length,width):
        self.length=length
        self.width=width
    def area(self):
        return self.length*self.width
        
class Square(Rectangle):
     pass
squ=Square(6,6)
print(squ.area())

执行结果:36

示例2:部分继承,不修改方法

class Rectangle:
    def __init__(self,length,width):
        self.length=length
        self.width=width
        
    def area(self):
        return self.length*self.width
        
class Square(Rectangle):
     def __init__(self,side):   #只对初始化方法进行修改
        self.length=side
        self.width=side
squ=Square(6)
print(squ.area())

执行结果:36


示例3:部分继承,继承方法的同时并补充

class Rectangle:
    def __init__(self,length,width):
        self.length=length
        self.width=width
        
    def area(self):
        return self.length*self.width
        
    @classmethod
    def features(cls):
        print('父类的类方法')
        
class Square(Rectangle):
    def __init__(self,side):
        self.length=side
        self.width=side
    @classmethod
    def features(cls):
        super().features()    # 继承父类的同名方法的代码
        print('子类的类方法')  # 补充
squ=Square(6)
squ.features()

执行结果:

父类的类方法
子类的类方法


示例4:多继承

class people:
    def __init__(self,n,a):   #构造方法
        self.name = n  
        self.__age = a       
    def speak(self,height):     #实例方法,其中height为实例属性
        print("%s 说: 我 %d 岁,身高 %d cm。" %(self.name,self.age,height))

class speaker():
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    def speak(self):
        print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))
 
#多重继承
class sample(speaker,people):
    def __init__(self,n,a,t):
        people.__init__(self,n,a)
        speaker.__init__(self,n,t)
 
test = sample("Tim",25,"Python")
test.speak()   #方法名同,默认调用的是在括号中排较前父类的方法

==>我叫 Tim,我是一个演说家,我演讲的主题是 Python

注:若父类中有相同的方法名,而在子类使用时未指定,python在父类中从左至右搜索

2、区分静态方法和类方法:

方式一:type()方法
静态方法返回function,类方法返回method

class people:           
    @classmethod  #声明下面是个类方法
    def f1(cls):
        print('这是类方法')

    @staticmethod  #声明下面是个静态方法
    def f2():
        print('这是静态方法')
        
print(type(people.f1))
print(type(people.f2))

执行结果:

<class 'method'>
<class 'function'>

方式二:inspect()函数
可利用inspect.ismethod()、inspect.isfunction()来判断

#追加代码
import inspect
print(inspect.ismethod(people.f1))
print(inspect.isfunction(people.f2))

执行结果:

True
True

3、私有属性、私有方法

  • 私有属性:不能被子类继承的属性
  • 私有方法:不能被子类继承的方法
  • 格式:在属性/方法前加"__",就成了私有的

① 直接调用私有:

class A:
    __name='private'  #私有属性
    def __init__(self):
        pass
    def __f1(self):  #私有方法
        print('这是一个私有方法')

a=A()
print(a.__name)  #调用私有属性
a.__f1()    #调用私有方法

执行结果:报错

AttributeError: 'A' object has no attribute '__name'
AttributeError: 'A' object has no attribute '__f1'

总结:直接调用私有属性、私有方法报错

② 通过继承调用私有:

class A:
    __name='private'  #私有属性
    def __init__(self):
        pass
    def __f1(self):  #私有方法
        print('这是一个私有方法')

class B(A):
    pass
b=B()
print(b.__name)
b.__f1()

执行结果:报错

AttributeError: 'B' object has no attribute '__name'
AttributeError: 'B' object has no attribute '__f1'


③ 间接调用

class A:
    __name='private'  #私有属性
    def __init__(self):
        pass
    def __f1(self):  #私有方法
        print('这是一个私有方法')
    def f2(self):
        print(self.__name)
        self.__f1()

a=A()
a.f2()

执行结果:

private
这是一个私有方法

4、object类

所有的类都是object的子类

class A:
    """A的注释"""
class B(object):
    """B的注释"""

print(A.__bases__)  #查看A的父类
print(A.__doc__)  #查看A的注释
print(A.__name__)  #查看A的类名
print(B.__bases__)
print(B.__doc__)

执行结果

(<class 'object'>,)
A的注释
A
(<class 'object'>,)
B的注释

5、多态

class A():
    def f1(self):
        print('A的f1')
class B():
    def f1(self):
        print('B的f1')
        
def f(obj):  
    obj.f1()

f(A())  
f(B())  

执行结果:

A的f1
B的f1

猜你喜欢

转载自blog.csdn.net/weixin_45128456/article/details/112188096