python面向对象及异常


面向对象的三个特征:封装 继承 多态

1 继承

1.1 继承的概念

什么是继承?
继承是指一个对象直接使用另一个对象的属性和方法。也指按照法律或遵照遗嘱接受死者的财产、职务、头衔、地位等
继承:
程序来说:指的是子类继承父类的属性和方法。

  • 单继承:指的是子类只有一个父类
  • 多继承:指的是子类有多个父类

1.2 单继承

如果在子类中没有定义__init__方法,但是父类中定义了此方法,那么子类继承父类的时候这个方法也被继承了,所以只要创建子类的对象,就默认执行了__init__这个方法
定义子类的格式:

class 子类名(父类名)
		#所有子类都有一个父类,父类是object

子类会继承父类的属性、方法
子类拥有父类的属性和方法,因此在子类中只需要定义自己的方法

  • 子类不能直接访问父类的私有属性和私有方法,但是我们可以在父类中通过父类 中的公有方法调用父类中的私有方法或父类中的私有属性。
  • 当子类和父类中同时存在某个方法的时候,优先调用子类中的方法
  • 如果子类中没有此方法,那么就调用父类中的方法
  • 查看子类调用顺序:类名.mro
  • 如果在子类中写了一个和父类中方法同名的方法,那么称之为重写父类中的方法
class Animal(object):
    def __init__(self):
        self.name='动物'
        self.age=0
        self.color=''
        self.__flag='独家'
    def run(self):
        print('动物会奔跑')
    def eat(self):
        print('动物吃食物')
    def __talk(self):
        print(self.__flag)
        print('特有的叫声')
    def A(self):
        self.__talk()
        print('A')
    def test(self):
        print('父类中的test方法')
class Cat(Animal):
    def test(self):
        print('cat的方法')
cat=Cat()
print(cat.name)
cat.run()
# cat.test()
# print(cat.__flag)
# cat.__talk()
cat.A()
cat.test()

print(Cat.__mro__)

结果:
在这里插入图片描述

1.3 多继承

多继承

  • 就是子类有多个父类,并且具有他们的特征

书写格式:

class 子类名(父类1,父类2,...):

子类继承父类的属性和方法
当子类中的属性或方法没有被定义的时候,去父类中查看,查看的顺序按照括
号里面的顺序进行搜索
重写父类方法
重写就是在子类中,有一个和父类同名的方法,在子类中的方法会覆盖父类中同名的方法

class Horse:
    def __init__(self):
        self.name='小马'
        self.__age=0
        self.color=''
    def run(self):
        print('这是马的奔跑方式')
    def test(self):
        print(self.color)
class Donkey:
    def __init__(self):
        self.name='xiaolv'
        self.__age=0
        self.color='棕'
    def run(self):
        print('驴的奔跑方式')
    def drank(self):
        print('驴喝水')
class Mule(Horse,Donkey):
    def X(self):
        print('骡子的方法')
mule=Mule()
mule.X()
mule.test()
mule.drank()
mule.run()
print(Mule.__mro__)

结果:
在这里插入图片描述

2 多态

2.1 多态的概念

多态:

  • 多态也是继承中的特点
  • 定义时的类型和运行时的类型不一样
  • 在定义的时候不明确使用的是谁的方法,只有在调用的时候才明确是哪一个
    类中的某个方法
class S1:
    def test(self):
        print('这是S1的test方法')
class S2:
    def test(self):
        print('这是S2的test方法')
def fun(a):
    a.test()
s1=S1()
fun(s1)

结果:
在这里插入图片描述

2.2 类属性和实例属性

  • 实例属性就是对象属性。
  • 类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本。
  • 对于公有的类属性,在类外可以通过类对象和实例对象访问。
  • 类属性是在类中直接声明的,类似于全局变量。

类属性的调用:
可以被实例化对象调用和类本身调用。

私有类属性:
和私有属性一样,在属性名前面加上两个下划线,不能直接在类的外部进行访问,但是可以在类的内部进行访问。

类属性的修改
1 类名.类属性名=值

  • 当通过类名和实例化对象访问这个类属性的时候,这个类属性的值是改变之后的值

2 对象名.类属性名=值

  • 本质上是给这个对象增加了一个实例属性,因为通过这种方法修改的属性的值,其实还是实例对象的属性的值,并没有修改类属性的值,因此通过类.类属性名的属性值没有被改变。
class Cat:
    name='小花'
    __color='蓝色'
    def __init__(self):
        self.age=12
    def test(self):
        print(Cat.__color)
        print(self.__color)
        print(self.age)
        print(self.name)
cat=Cat()
# cat.test()
Cat.name='肖类'
# print(Cat.name)
# print(Cat.__color)
# cat.name='晓晓'
print(cat.name)
print(Cat.name)

结果:
在这里插入图片描述
总结

  • 如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。
  • 如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。

2.3 类方法和静态方法

类方法

  • 类方法时类对象所拥有的方法,需要用修饰器@classmethod标识为类方法。

  • 类方法第一个参数必须是类对象,一般以cls作为第一个参数,能够通过实例对象和类对象去访问。

  • 类方法可以对类属性进行修改。
    类方法的访问:

  • 可以被类本身访问和实例化对象访问

    静态方法

  • 通过@staticmethod修饰,静态方法不需要多定义参数

类方法的调用
公有类方法:实例化对象 类 实例方法

私有类方法:不能在类的外部直接访问,但是可以在类内部进行访问
在类的内部可以被实例方法 和 类方法访问

注释:
在同一个类中,方法名不要相同

class A:
    name='小花'
    __age=0
    def __init__(self):
        print('init')
    def test(self):
        self.__test2()
        print('a')
    @classmethod
    def test1(cls):
        cls.__test2()
        cls.name='小蓝'
        print('test')
        print(cls.name)

    @classmethod
    def __test2(cls):
        cls.__age=3
        print(cls.__age)
a=A()
# a.test()
# a.test1()
# A.test1()
a.test()

结果:
在这里插入图片描述

3 异常

3.1 异常介绍

异常:
python解释器检测到错误的时候,无法继续运行程序
常见异常:
ZeroDivisionError:除数不能为0
IndexError:索引异常,超出索引的范围
NameError:变量没有定义
FileNotFoundError:文件没有找到
classnotfound:没有找到类

3.2 捕获异常(处理方式)

try-except
把那些可能出现异常的代码放入到try代码块中
except代码块中的代码会在try代码块中出现问题的时候运行
try-except-except
except可以有多个子句
顺序:需要把最大的那个异常放到最后,因为当程序直接捕捉到最大的异常的时候
,不会执行后面的except子句。

try:
    print(b)
    #错误示范,Exception最大异常,需要放到最后
except(Exception):
    print('程序出错')
except(FileNotFoundError):
    print('文件没有找到')
except(NameError):
    print('变量没有定义')

结果:(先经过最大异常检测,所以直接出来结果)
程序出错

try-except(多个)
如果把except多个子句写成一个except子句的时候,在括号里面写入异常的类型,
用逗号隔开,同样也是把最大的异常写在最后

try:
    print(b)
    a=10/0
    print(a)
except(ZeroDivisionError,IndexError,NameError):
    print('程序出错')

try-except-finally
finally子句中,无论上面的代码是否需要捕捉异常,那么都会执行的代码

try:
    f=open('k.txt')
    content=f.read()
    print(content)
except(FileNotFoundError):
    print('文件没有找到')
finally:
    try:
        f.close()
    except:
        print('aaa')

结果:
在这里插入图片描述
try-except-else
当try中的代码没有错的时候,那么执行else里面的,如果在try中有异常的时候,
执行except子句中的代码

try:
    a=10/1
except:
    print('-----------')
else:
    print('end')

结果:
在这里插入图片描述
自定义异常类:
如何定义异常类:

    需要继承存在的异常类,通常我们继承的是Exception
    class MyExceptin(Exception)

有时候,python给我们提供的异常不满足
比如:从键盘上接收数字,如果长度>3,抛出异常,长度不能大于3
所以需要自己定义异常类

class MyLengthException(Exception):
    def __init__(self,length):
        super().__init__()
        self.length=length
    def __str__(self):
        return 'Error[1023] num length not gt 3'
def main():
    try:
        s=input('请输入一个字符串:')
        if len(s)>3:
            raise MyLengthException(len(s))
        else:
            print(s)
    except MyLengthException as result:
        print('有异常发生,这个异常是:%s'%result)
main()

结果:
在这里插入图片描述
在这里插入图片描述

4 单继承和圆柱

计算圆柱的表面积和体积:

class Circle:
    def __init__(self,r):
        self.r=r
    def getArea(self):
        self.area=3.14*self.r*self.r
        return self.area
    def getPerimeter(self):
        self.perimeter=2*3.14*self.r
        return self.perimeter
    def __str__(self):
        return str(self.getPerimeter())+'\t'+str(self.getArea())
class CircleRect(Circle):
    def __init__(self,r,h):
        # Circle.__init__(self,r) # 第一种调用父类中的初始化方法
        super().__init__(r) # 第二种调用父类中的初始化方法
        self.h=h
    def getSFA(self):
        self.sfa=2*self.getArea()+self.getPerimeter()*self.h
        return  self.sfa
    def getV(self):
        self.v=self.getArea()*self.h
        return self.v
    def printInfo(self):
        print('圆柱的表面积是'+str(self.getSFA())+'\n'+'圆柱的体积是'+str(self.getV()))
ct=CircleRect(3,2)
ct.printInfo()

结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值