Python面向对象思想

类是模板,对象是根据这个模板创建出来的,应该先有类,再有对象

类只有一个,但对象可以有很多个。

不同的对象之间属性可能会各不相同

类中定义了什么属性和方法,对象中就有什么属性和方法,不可能多也不可能少。

在程序开发中,要设计一个类,通常需要满足以下三个要素:

1、类名:这类事物的名字,满足大驼峰命名法(每个单词首字母大写)

2、属性:这类事物具有什么样的特征

3、方法:这类事物具有什么样的行为

特征一:封装

将属性和方法封装到一个抽象的类中,外界只需要创建类所对应的对象,由对象调用属性或方法。

class User():#定义类,()内为空默认继承object类
    def __init__(self,username,password,age,address):
        self.username = username
        self.password = password
        self.age = age
        self.address = address

    def eat(self,food):
        print(self.username+"吃饭"+food)

    def add(self,*num):
        number = 0
        for i in num:
            number += i
        return number

    def __str__(self):
        return "用户名:%s,密码:%s,年龄:%s,地址:%s"%(self.username,self.password,self.age,self.address)

user1 = User("张三丰","123456",100,"武当山") #定义对象
print(user1)
user1.eat("盖饭")
sum = user1.add(1,2,3,4,5)
print("sum=%s"%sum)

运行结果:

用户名:张三丰,密码:123456,年龄:100,地址:武当山
张三丰吃饭盖饭
sum=15
面向对象需要关注的特殊方法
__init__() 初始化函数
__str__()  用来输出对象详细信息
__new__()  用来开辟内存空间
__der__()  销毁对象信息
dir() 罗列可操作
#单例设计模式
class Person():
    obj_instance = None

    def __new__(cls,*args,**kwargs):
        print("开辟内存空间")

        if cls.obj_instance is None:
            cls.obj_instance = super().__new__(cls)

        return cls.obj_instance

    def __init__(self):
        print("初始化信息")

    def __del__(self):
        print("销毁")

person1 = Person()
person2 = Person()
person3 = Person()
person4 = Person()
print(person1)
print(person2)
print(person3)
print(person4)

运行结果:

开辟内存空间
初始化信息
开辟内存空间
初始化信息
开辟内存空间
初始化信息
开辟内存空间
初始化信息
<__main__.Person object at 0x0000021E8F93DF70>
<__main__.Person object at 0x0000021E8F93DF70>
<__main__.Person object at 0x0000021E8F93DF70>
<__main__.Person object at 0x0000021E8F93DF70>
销毁

可以看出四个对象使用同一个地址,单例模式可以节省存储空间,但是可能会出现多线程环境下的线程安全问题等。

私有属性和私有方法

私有属性:对象内部使用,不希望外界直接调用的属性

私有方法:对象内部使用,不希望外界直接调用的方法

定义方法:在定义属性或方法时,可以在属性或方法前追加双下划线__

class Person:
    def __init__(self,name):
        self.name = name
        self.__age = 18

    def __sal(self):
        print("我的年龄是:%s,不要随便询问工资"%self.__age)

zhangsan = Person("张三")
print(zhangsan.name)
print(zhangsan.__age) #私有属性无法调用
zhangsan.__sal #私有方法无法调用

运行结果:

张三
报错信息:
AttributeError: 'Person' object has no attribute '__age'
AttributeError: 'Person' object has no attribute '__sal'

在python中,没有真正意义上的私有,只是通过双下划线做了特殊处理在日常生活中,不建议使用伪私有属性或伪私有方法,但是如果需要访问,可以用特殊方法暴力访问到。

访问方法:在名称前追加_类名

print(zhangsan._Person__age)
zhangsan._Person__sal()

运行结果:

18
我的年龄是:18,不要随便询问工资

特征二:继承

继承可以实现代码的重用,相同的代码不需要进行重复的编写。

子类可以使用父类的属性或方法

继承的基础使用

不使用继承时:

不使用继承
class Cat:
    def eat(self):
        print("吃饭")

class Dog:
    def eat(self):
        print("吃饭")

class Rabbit:
    def eat(self):
        print("吃饭")

三个类似的类有相同的行为(方法),需要写三遍相同的代码。

可以使用继承:

class Animal: #父类
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def eat(self):
        print(self.name+"吃饭")                                                


class Cat(Animal):
    def __init__(self,name,age,address): #子类初始化
        super().__init__(name,age)
        self.address = address

    def catch_mouse(self):
        print(self.name+"在"+self.address+"抓老鼠")

class Dog(Animal):  #不写初始化默认使用父类初始化
    def look_door(self):
        print("看大门")

class Rabbit(Animal):
    pass

tom = Cat("汤姆",3,"中北大学")
tom.eat() #使用父类方法
tom.catch_mouse()

dog = Dog("金毛",4)
dog.eat()  #使用父类方法
dog.look_door()

运行结果:

汤姆吃饭
汤姆在中北大学抓老鼠
金毛吃饭
看大门

继承的传递性:

A类继承B类,B类继承C类,A拥有B类和C类两个类中的信息。

class C():
    def study(self):
        print("学习")

class B(C): #继承C类
    pass

class A(B): #继承B类
    pass

a = A()
a.study() #使用C类的方法

​

运行结果:

学习

方法的重写

当子类继承父类,可以直接使用父类的相关方法,但是如果需要有子类特定的相关业务逻辑,子类可以把父类的方法进行重写(方法的复写、覆盖)

class Animal():
    def eat(self):
        print("吃饭")

class Cat(Animal):
    def eat(self):  #重写父类eat方法
        print("猫吃鱼")

class Mouse(Animal):
    def eat(self):  #重写父类eat方法
        print("老鼠吃大米")

tom = Cat()
tom.eat()
jerry = Mouse()
jerry.eat()

运行结果:

猫吃鱼
老鼠吃大米

应用场景:在开发过程中,父类提供相关的方法设计,但是不同的子类拥有不同的方法的实现,在这种状况下,可以对方法进行重写。当发生方法的重写,在运行时,调用到的是重写之后的方法,而不再是父类的方法。

对父类方法的拓展:如果想使用父类的方法,可以使用super关键字。

例如修改上述Cat类为:

​class Cat(Animal):
    def eat(self):
        super().eat() #调用父类方法
        print("猫吃鱼")

​

那么Cat类对象调用eat方法的运行结果为:

吃饭
猫吃鱼

多继承的注意事项

当不同的父类中出现了相同的方法名称,那么子类在调用父类的方法时,根据子类继承多个父类的先后顺序来判定哪一个方法来执行。

class User:
    def study(self):
        print("user类学习")

class Person:
    def study(self):
        print("person类学习")

class Student(User,Person): #先继承的User,然后是Person
    pass

zs = Student()
zs.study()  #调用study方法,由于先继承的User,调用User的study方法

运行结果:

user类学习

一般在研发项目中,尽量不要出现继承的多个父类有同名方法的现象,或者避免出现多继承。

在python中提供了验证多继承顺序的模块mro,例如:

print(Student.__mro__)

运行结果:

(<class '__main__.Student'>, <class '__main__.User'>, <class '__main__.Person'>, <class 'object'>)

得到Student类优先级为Student类>User类>Pserson类>object类

新式类与旧式类

新式类:以object为基类

旧式类:不以object为基类

注意:在python3.以后,创建类如果没有继承类,那么默认继承object,都属于新式类。

继承中初始化注意事项

在子类没有提供初始化init方法的时候,初始化子类会先初始化父类init函数,若子类提供了初始化iinit方法,则默认不在父类初始化,但是在需要使用父类的一些初始化属性时会报错。

class A:
    def __init__(self):
        print("父类的初始化函数")
        self.data = []

    def addData(self,str):
        self.data.append(str)
        print(self.data)

    def help(self):
        print("通用帮助文档")

class B(A):
    def __init__(self):
        print("子类的初始化函数")

b = B() 
b.help()
b.addData("hello")

运行结果:

子类的初始化函数
通用帮助文档

报错信息:
AttributeError: 'B' object has no attribute 'data'

原因:子类手动提供了初始化init方法,导致默认不执行父类的初始化init方法。

解决方法:建议在后续开发过程中,养成一个好习惯,当在子类中手动提供初始化init方法的时候,手动通过super方法调用父类的初始化init函数。

class B(A):
    def __init__(self):
        print("子类的初始化函数")
        super().__init__()  #手动执行父类初始化

抽象类

抽象类中设置抽象方法(方法为空),实体类继承抽象类后,规范了方法的名称和个数,继承它的实体类需要实现抽象类中的所有方法。

在项目统一开发中可以使用抽象类,来规范类的方法命名和书写,以免造成混乱。

from abc import abstractmethod,ABCMeta
class UserDao(metaclass=ABCMeta):  #创建抽象类
    @abstractmethod    #抽象方法
    def addUser(self):
        pass

    @abstractmethod   #抽象方法
    def deletUser(self):
        pass

    @abstractmethod  #抽象方法
    def updataUser(self):
        pass

    @abstractmethod   #抽象方法
    def getUser(self):
        pass

class UserTest(UserDao):  #继承抽象类
    def addUser(self):
        print("添加用户")

    def deletUser(self):
        print("删除用户")

    def updataUser(self):
        print("修改用户")

    def getUser(self):
        print("查询用户")

test = UserTest()
test.addUser()
test.deletUser()
test.updataUser()
test.getUser()

运行结果:

添加用户
删除用户
修改用户
查询用户

特征三:多态

多态指的是不同对象对同一方法做出的不同相应,具体来说,多态允许我们使用相同的接口(方法名)来操作不同的对象,而这些对象会根据它们自己的类型来执行相应的行为。

python中处处是多态,多态可以增加代码的灵活度,这里简单写一个案例:

class Dog:
    def __init__(self,name):
        self.name = name

    def game(self):
        print("名字为 %s 的狗在玩耍..."%self.name)

class JinMaoDog(Dog):
    pass

class Taidi(Dog):
    pass

class Person:
    def __init__(self,name):
        self.name = name

    def playWithDog(self,dog):
        print("%s 与 %s 正在快乐地玩耍.."%(self.name,dog.name))

dog = Dog("流浪狗")
jinmao = JinMaoDog("金毛")
taidi = Taidi("泰迪")

zs = Person("张三")

jinmao.game()
zs.playWithDog(dog)

运行结果:

名字为 金毛 的狗在玩耍...
张三 与 流浪狗 正在快乐地玩耍..

OA源代码C#漂亮通用OA企业办公系统 OA人事办公软件asp.net源码1、开发环境为Visual Studio 2012,数据库为SQLServer2008或以上版本,使用.net 4.0+开发。2、管理员登陆名为:admin 密码:admin3、默认数据库连接字符串在webconfig配置文件中修改4、修改版为数据库请使用【备份数据库文件】中.bak文件还原即可1、包含常用办公所有功能(财务,档案,人力资源,审批,会议,文件,业务等功能);2、多年的技术积累和大量用户需求的汇总调整,保证了系统的安全性稳定性、易操作、管理维护简单的特点;3、系统设计开发的规范性与全面性,利于系统的实现、测试、维护、版本升级等。开发人员既可全面了解OA系统所涉及的业务,也能对本身技术提升有所助益,同时减轻了团队开发压力,节约了开发成本;4、采用B/S架构,用户通过浏览器即能进行联网访问办公。功能介绍1、个人办公a、内部邮件b、Internet邮件c、通讯薄d、个人设置2、审批流程a、审批流程b、流程设置c、印章管理3、公文收发a、公文收发4、工作管理a、工作管理5、下属任务a、下属任务6、知识文档a、知识文档7、扩展应用a、资产管理b、培训记录c、会议管理d、车辆管理e、图书管理f、档案卷库g、考试管理h、学习管理8、客户关系a、会员管理b、我的客户c、客户管理9、进销存类a、产品管理b、销售管理c、采购管理d、供应商管理e、财务模块10、项目管理a、项目管理11、人力资源a、考勤管理12、报表中心a、报表中心13、信息交流a、信息交流14、组织机构a、组织机构15、附件程序a、附件程序16、系统管理a、系统管理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值