python笔记三之面向对象(继承,封装,多态)

类和对象:

类是一组具有相同特征或者行为的事物的统称,是抽象的,不能直接使用
特征被称为属性
行为被称为方法
类的名命名,满足大驼峰的命名方法
对象是由类创建创建出来的具体存在的事物,可以直接使用
在自己定义的类中,能够定义属性和方法
类是模板,对象是根据类这个模板创建出来的,先有类,后有对象
类只有一个,而对象只有一个
不同的对象属性可能不同,类中有的属性和方法,对象就能调用这些属性和方法

python面向对象的基础语法

在这里插入图片描述
使用内置函数的dir可以查看到对象的所有属性和方法

定义类的方法:

class 类名:
    def 方法名1(self,参数列表):
        pass
    def 方法名2(self,参数列表):
    pass

创建对象:

对象名=Cat()
对象名.方法名
在计算机中,通常使用十六进制表示内存地址
%d可以以10进制输出数值
%x可以以16进制输出数字

哪个对象调用的方法,self就是哪个对象的引用

class Cat:
    def eat(self):
        print("%s爱吃鱼"%self.name)
    def drik(self):
        print("小猫爱喝水")
tom=Cat()
tom.name="Tom"
tom.drik()
tom.eat()
print(tom)
lazy_Cat=Cat()
lazy_Cat.name="dalanmao"
lazy_Cat.eat()
lazy_Cat.drik()
print(lazy_Cat)

初始化方法:
在python中专门用来定义一个类具有哪些属性的方法是__init__,这是对象的内置方法

class Cat:
    def __init__(self):
        print("初始化")
tom=Cat()
python中在使用类名()创建对象的时候,会自动调用初始化方法__init__

在初始化方法内部定义属性:

在__init__方法内部使用self.属性名=属性的初始值,就能定义属性
在定义属性之后,在使用Cat类创建对象,就能够调用该属性
__del__如果希望在对象销毁之前在做一些事情,就是用__del__方法
如果在开发中,希望使用print输出对象时,能够打印自定义的内容,就要用__str__这个内置方法返回的是一个字符串,不能直接打印,只能使用return返回
封装是面向对象的一大特征,将属性和方法都封装到一个类中,同一个类创建的对象,属性之间互不影响
在python中定义一个类之后需要再定义一个类,则需要空出两行重新写
在Python中如果不知道设置什么初始值,可以设置为None,None 表示一个空的对象,没有方法和属性值,是一个特殊的常量,可以赋值给任何的一个变量,在python中针对None进行比较时,使用is进行判断

面向对象实例一(摆家具)

#首先定义家居类,属性name,area,使用__str__内置函数返回家具的名称和家具的占地面积
class HouseItem:
    def __init__(self,name,area):
        self.name=name
        self.area=area
    def __str__(self):
        return"家具的名称是%s,家具的占地面积是%.2f"%(self.name,self.area)

#创建一个房子类,房子的属性有house_type,总的占地面积area,空余的面积:free_area,家居类的列表,__str__内置函数输出房子的户型,房子的总面积,和房子的剩余面积,输出家具列表
#行为有add()方法,用于添加家具,
class House:
    def __init__(self,house_type,area):
        self.house_type=house_type
        self.area=area
        self.free_area=area
        self.item_list=[]
    def __str__(self):
        return ("户型:%s\n总面积:%.2f\n[剩余面积:%.2f]\n家具:%s"
                %(self.house_type,self.area,
                  self.free_area,self.item_list))
    def add(self,item):
        print("要添加的家具%s"%item)
        #判断家具面积
        if item.area>self.free_area:
            print("%s面积太大了,无法添加"%item)
            return
        self.item_list.append(item.name)
        self.free_area-=item.area

        #将家具添加到列表中
        #计算剩余面积
# 创建三个家具类
bed=HouseItem("席梦思",40.0)
chest=HouseItem("衣柜",2.0)
table=HouseItem("餐桌",1.5)
print(bed)
print(chest)
print(table)
# 创建一个房子类,调用添加家具的方法
my_home=House("别墅",60)
my_home.add(bed)
my_home.add(chest)
my_home.add(table)
print(my_home)

面向对象实例二(士兵突击)

#创建一个枪的类,属性为枪的类型,行为是添加子弹,和射击
class Gun:
    def __init__(self,model):
        self.model=model
        self.bullet_count=0
    def add_bullet_count(self,count):
        self.bullet_count+=count
    def shoot(self):
        # 1.判断子弹数量
        if self.bullet_count<=0:
            print("%s没有子弹了,需要重新装填"%self.model)
            return
        # 2.发射子弹
        self.bullet_count-=1
        # 提示发射
        print("[%s]开始发射!【%d】"%(self.model,self.bullet_count))

# 创建一个士兵的类,属性是名字,行为是开火
class Soldier:
    def __init__(self,name):
        self.name=name
        self.gun=None
    def fire(self):
        #判断是否有枪
        if self.gun is None:
            print("【%s】还没有得到枪"%self.name)
            return
        #士兵高喊口号
        print("冲啊!...【%s】"%self.name)
        #士兵装填子弹
        self.gun.add_bullet_count(50)
        #枪发射子弹
        self.gun.shoot()
ak=Gun("ak47")
sanduo=Soldier("许三多")
sanduo.gun=ak
print("%s的枪是"%sanduo.name,sanduo.gun)
sanduo.fire()

身份运算符:

身份运算符用于比较两个对象的内存地址是否一致,是否是一个对象的引用
运算符 描述 实例
is is是判断两个标识符是不是引用同一个对象 x is y,类似id(x)id(y)
is not is not是判断两个标识 x is not y, 类似于id(x)!=id(b)
is 和
的区别:
is 用于判断两个变量的引用对象是否为同一个,比较的是内存的地址
== 用于判断引用变量的值是否想等

私有属性和私有方法:

在实际开发中,对象的某些属性和方法只希望在对象的内部使用,而不希望在外部被访问到
私有属性:对象不希望被公开的属性,不能够被直接访问
私有方法:对象不希望被公开的方法,不能被直接访问
定义的方式:
在定义属性和方法的时候,在属性名称或者和方法名称前面增加两个下划线,定义的就是私有的的属性和方法

Person
name__age
__init__(self,name):_secret(self):
私有方法的实例:
class Women:
    def __init__(self,name):
        self.name=name
        self.__age=15
    def secret(self):
        print("%s的年龄是%d"%(self.name,self.age))
xiaohong=Women("小红")
print(xiaohong.age)
print(xiaohong.name)
xiaohong.secret()
无法进行访问,age的属性是私有保护的,不能进行直接访问

伪私有属性和方法:
python没有真正意义的私有
在给属性和方法命名时,_类名__age

继承:

面向对象的三大特性:
封装: 根据职责将属性和方法封装到一个抽象的类中
继承:实现代码的重用,相同的代码不需要重新编写
单继承:
子类拥有父类的所有的属性和方法,继承具有传递性

继承的语法:
class 类名(父类名):
pass
dog类是animal类的派生类,animal是dog类的基类,dog类从animal类中派生

方法的重写:

子类拥有父类的所有的方法和属性
子类继承父类,可以使用父类中已经封装好的方法,当父类中的方法不能实现满足子类时,可以重写该方法
1.覆盖父类中的方法
在子类中定义一个和父类同名的方法并且实现。重写后会调用子类重写的方法,而不会再调用父类封装的方法

class Animal:
    def eat(self):
        print("吃东西")
    def run(self):
        print("跑步吧!")
    def sleep(self):
        print("睡觉觉")
class Dog(Animal):
    def bark(self):
        print("汪汪汪!")
class Xiaoming(Dog):
    def fly(self):
        print("我会飞!")
    def bark(self):
        print("我是二郎神下的一只神狗")
xiaotian=Xiaoming()
xiaotian.bark()
xiaotian.fly()
xiaotian.eat()

2.对父类进行扩展
重写父类中的方法
在需要的位置使用super().父类方法来调用父类方法的执行
代码其他的位置针对子类的需求,编写子类的特有方法实现
关于super
在python中supe()是一个特殊的类,super()就是使用super类创建出来的对象
常用在重写父类的方法时,调用父类中的封装方法实现

02多继承:

python支持多继承,子类可以拥有多个父类,并具有所有父类的属性和方法,在开发中,如果父类中存在同名的属性或者方法,应该尽量避免使用多继承
列如:孩子会继承父亲和母亲的特性
语法格式:

class 子类名(父类名1,父类名2....)
pass
class A:
    def test(self):
        print("小朋友!嘻嘻嘻")
class B:
    def demo(self):
        print("你好,请多多指教!")
class C(A,B):
    def tube(self):
        print("啦啦啦啦!")
c=C()
c.test()
c.tube()
c.demo()

object是python中为所有对象提供的基类,提供的有内置的方法和属性,可以使用dir查看
在定义类的时候,如果没有父类,建议继承来自object

class 类名(object):
pass

多态:不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度
多态可以增加代码的灵活度
以继承和重写父类的方法为前提
是调用的技巧,不会影响到内部的设计

面向对象之继承案列一:

class Dog:
    def __init__(self,name):
        self.name=name
    def game(self):
        print("%s玩毛线"%self.name)
class Xiaotianquan(Dog):
    def game(self):
        print("%s喜欢在天上玩毛线"%self.name)
class Person:
    def __init__(self,name):
        self.name=name
    def game_withdog(self,dog):
        print("%s喜欢和%s玩"%(self.name,dog.name))
dog=Xiaotianquan("哮天犬")
dog.game()
xiaoming=Person("小明")
xiaoming.game_withdog(dog)

创建出来的对象叫做类的实例
创建对象的动作叫做实例化
对象的属性叫做实例的属性
对象的调用方法叫做实例方法
每个对象都有自己的独立的空间,保存着各自独立的属性
多个对象的方法,在内存中只有一份,在调用方法是,需要把对象引用传递到方法内部
类是一个特殊的对象:
python中万物皆对象
class Person:定义类属于类对象
obj=Person() 实例化对象
在程序运行的时候,类会被加载到内存
在python中,类是一个特殊的对象—类对象
在程序运行的时候,类对象在内存中,只有一份,使用一个类就能创建出很多个对象实例
除了封装实例的属性和方法,可以有自己的属性和方法
类属性
类方法
类属性就是给类对象定义的属性,通常用来记录与这个类相关的特征(列如:能够记录创建工具对象的个数),类属性不会用来记录具体对象的特征

class Person:
    #使用赋值语句定义类的属性,记录所有工具对象的数量
    count=0 
    def __init__(self,name):
        self.name=name
        #类属性的值+1
        Person.count+=1
xiaohong=Person("袁亚茹")
yangguanbing=Person("杨冠宾")
print(Person.count)

类方法:
类方法就是针对类对象定义的方法,在类方法内部可以直接访问类的属性或者调用其他的类方法

@classmethod
def 类方法名(cls):
    pass

类方法需要修饰器@classmethod来标识,告诉解释器这是一个类方法
类方法的第一个参数是cls
由哪一个类调用的方法,方法内的cls就是哪一个类的引用
与实例方法中的第一个参数是self类似
通过类名调用类方法,调用时不需要传递参数cls
在方法内部
可以使用cls.访问类的属性
也可以通过cls.调用其他的类方法
面向对象案列之类方法的调用

class Person:
    count=0
    def __init__(self,name):
        self.name=name
        Person.count+=1

    @classmethod
    def test(cls):
       print("工具类的数量是%d"%cls.count)
       
yuanyaru=Person("袁亚茹")
yangguanbing=Person("杨冠宾")
Person.test()

静态方法:
在开发的时候,如果需要在类中封装一既不需要访问实例属性,也不需要访问类属性大的方法,可以将这个方法定义为静态方法
语法如下:
@staticmethod
def 静态方法名():
    pass

静态方法需要使用@staticmethod来标识,告诉解释器这是一个静态的方法,通过类名. 来调用静态的方法
综合案列一:
class Game:
    #定义类属性,记录历史最高分:
    top_score=0
    #定义类方法显示最高分
    @classmethod
    def show_top_score(cls):
        print("历史最高分%d"%cls.top_score)
    #定义游戏的帮助信息
    @staticmethod
    def show_help():
        print("帮助信息,让植物充满世界!")
    #实例化属性
    def __init__(self,name):
        self.player_name=name
    #实例方法
    def start_game(self):
        print("%s开始游戏了"%self.player_name)
Game.show_help()
Game.show_top_score()
test=Game("杨冠宾")
test.start_game()

异常的概念:
程序在运行的时候,如果遇到一个错误,就会停止程序的执行,并且显示一些错误信息,这就是异常
在程序停止执行结束后提示这个错误信息,就叫做抛出异常
捕获异常:
在程序开发中,如果对某些代码的执行不能确定是否正确,可以增加try(尝试)来捕获异常:

try:
    不确定是否执行的代码
except:
    出现的错误的时候,对错误的处理代码!

当python的解释器抛出异常的时候,最后一行错误信息的第一个单词就是错误类型

try:
    num=int(input("请输入一个整数!"))
except:
    print("请输入正确的整数!")
    print("--"*50)

捕获未知的错误:

如果希望程序无论出现任何错误,都不会因为python解释器抛出异常而被终止,可以增加一个except

except Exception as result:
    print("未知错误 %s"%result)

案例

try:
    num=int(input("请输入一个整数!"))
except Exception as result:
    print("未知错误%"%result)

异常捕获的完整语法:
在这里插入图片描述

else只有在没有异常的时候才会执行的代码
finally无论是否有异常,都会执行的代码
异常的传递:
当函数或者方法执行出现异常,会将异常传递给函数方法的调用的一方
如果传递到主程序,仍没有异常处理,程序会终止
在开发中,在主程序中增加异常的捕获,主函数中调用的其他的函数,只要出现异常,就会传递到主函数的异常的捕获中,保证代码的整洁

def dom1():
    return int(input("输入整数"))

def dom2():
    return dom1()
    #利用异常的传递性,在主程序中捕获异常
try:
    print(dom2())
except Exception as result:
    print("%s"%result)

抛出raise异常

在开发中除了python的解释器会抛出异常外,还可以根据应用程序特有的需求,主动抛出异常
创建一个Exception的对象
使用rise关键字抛出异常对象

input_password():
    #提醒用户输入密码
    pwd=input("请输入密码:")
#判断密码的长度>=8返回用户输入的密码
    if len(pwd)>=8:
        return pwd
#如果<=8主动抛出异常
    else:
        print("主动抛出异常!")
        # 创建异常的对象,可以使用错误信息作为参数
        es=Exception("密码长度不是太够")
        #主动抛出异常
        raise es
#当对象没有任何返回的时候,就会输出一个空对象None
try:
    print(input_password())
except Exception as result:
    print(result)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值