Python16-面向对象&类和对象&构造函数

一、面向对象

1.概念

1.1面向对象的设计思想

面向对象是基于万物皆对象这个哲学观点。在Python中,一切皆对象

举例说明:

案例一:我想要吃大盘鸡

面向过程 							面向对象

1.自己去买菜						    1.委托一个会砍价的人帮忙去买菜

2.自己择菜						    2.委托一个临时工帮忙择菜

3.自己做菜						    3.委托一个厨师帮忙做菜

4.自己开始吃						    4.自己开始吃



案例二:小明是一个电脑小白,想要配一台电脑,买完零件后需要运到家里,组装完成后打开电脑玩游戏

面向过程 							面向对象

1.小明补充电脑知识				1.委托一个懂电脑的朋友(老王)去帮忙买零件

2.小明去买零件				    	2.委托一个能跑腿的人去买零件

3.小明把零件带回家里				3.委托一个会组装电脑的人帮小明组装电脑

4.小明组装电脑				    	4.小明自己打开电脑,开始玩游戏

5.小明开机玩电脑	

	       

案例三:一辆白色的奥迪Q5在京藏高速上行驶

这里的奥迪Q5就是一个对象,京藏高速也是一个对象

1.2面向过程和面向对象的区别【面试题】

面向过程

在生活案例中:

一种看待问题的思维方式,在思考问题的时候,着眼于问题是怎样一步一步解决的,然后亲力亲为的去解决问题	

在程序中:

代码从上而下顺序执行

   各模块之间的关系尽可能简单,在功能上相对独立

每一模块内部均是由顺序、选择和循环三种基本结构组成

其模块化实现的具体方法是使用子程序

程序流程在写程序时就已决定

面向对象

在生活案例中:

也是一种看待问题的思维方式,着眼于找到【一个具有特殊功能的具体个体,然后委托这个个体去做某件事情】,我们把这个个体就叫做对象,一切皆对象

是一种更符合人类思考习惯的思想【懒人思想】,可以将复杂的事情简单化,将程序员从执行者转换成了指挥者

在程序中:

把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象

1》对同类对象抽象出其共性,形成类

2》类中的大多数数据,只能用本类的方法进行处理

3》类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信

4》程序流程由用户在使用中决定

5》使用面向对象进行开发,先要去找具有所需功能的对象,如果该对象不存在,那么创建一个具有该功能的对象

注意:面向对象只是一种思想,并不是一门编程语言,也不会绑定编程语言

面向过程和面向对象的优缺点【面试题】

面向过程:

优点:性能比面向对象高,开销比较大,比较消耗资源,比如单片机、嵌入式开发等一般采用面向过程开发,因为性能是最重要的因素

缺点:没有面向对象易维护,易复用,易扩展

面向对象:

优点:易维护,易复用,易扩展,由于面向对象有封装,继承,多态的特性,可以设计出低耦合的系统,使得系统更加灵活,更加易于维护

缺点:性能比面向过程低

Python是一门面向的语言,面向对象语言的特点:封装,继承和多态

狗吃屎:面向对象

吃狗屎:面向过程

2.类和对象

2.1概念

类:一个具有特殊功能的实体的集合【群体】,是抽象的

对象:在一个类中,一个具有特殊功能的实体,能够帮忙解决特定的问题【对象也被称为实例】,是具体的

两者之间的关系:类用于描述某一类对象的共同特征,而对象则是类的具体存在(包含关系)

问题:先有对象还是先有类?

【不好说,但是,一般在程序中,都是先定义类,然后通过类创建对象】

举例:

			类								对象

			人							张三、李四、王麻子、杨阳。。。

			SuperHero             蝙蝠侠、蜘蛛侠、美国队长。。。

			快递   					 顺丰、圆通、申通、韵达。。。

帮助理解:类也是一种数据类型,只不过是自定义的【系统类ValueError,NameError….】,跟所学过int,str,bool等类似。用类实例化对象相当于定义一个类的变量

num = 10
print(type(num))   # <class 'int'>

# 定义类Person
p = Person()   
print(type(p))    # <class '__main__.person'>

2.2类的定义和对象的创建

格式:

class 类名():

类体

说明:

a.Python中使用class关键字定义类

b.类名只要是一个合法的标识符即可,但是要求:遵循大驼峰命名法 ,如:KeyError,ValueError,NameError,IndexError…….

c.尽量使用单个或多个有意义的单词连接而成	

d.通过缩进来体现类体的存在

e.类体一般包含两部分内容:对类的特征描述和行为描述

# 一、类的定义
print("start~~~~~")
class MyClass1():
    print("1111")
class MyClass2():
    print("2222")
class MyClass3():
    print("3333")
class MyClass4():
    print("4444")

print("over~~~~~")

"""
注意:
    a.在同一个py文件中,可以同时定义多个类,但是,在复杂的需求中,一般是一个模块定义一个类
    b.class xxx(): 表示类的声明,类名尽量遵循大驼峰命名法,()可以省略,但是在Python3.x中,建议加上
    c.缩进的内容被称为类体【类的实现】,在其中会定义类的成员【类的特征描述和行为描述】,
      一个类一旦定义完成之后,其中的的成员会被加载
"""

# 二、对象的创建/类的实例化/对象的实例化
# 语法:类名(....)
num = 10
print(type(num)) # <class 'int'>
print(MyClass1)  # <class '__main__.MyClass1'>

mc1 = MyClass1()
print(type(mc1))  # <class '__main__.MyClass1'>
print(id(mc1))
print(mc1)

mc2 = MyClass1()
print(mc2)

mc3 = MyClass1()
print(mc3)


"""
注意:
    a.假设定义类MyClass,直接使用MyClass表示类名,同时表示一种数据类型,使用MyClass()表示创建对象
    b.m = MyClass(),m本质是一个变量,该变量的类型是MyClass类型,变量m中存储的是创建出来的对象的地址
    c.MyClass()该代码执行一次,则表示创建一个新的对象
    d.一般情况下,一个类可以创建无数个对象
"""

2.3类的设计

只需要关心3样东西

事物名称(类名):人类(Person)

特征:身高(height)、年龄(age)—————》名词———》变量

行为:跑(run)、打架(fight)———————》动词————》函数

初期学习,通过提炼动名词进行类的提取

3.类中的成员

3.1定义和访问

# 一、类中成员的定义
# 1.定义类
class Person():
    # 类体:特征和行为
    # 2.特征:变量

    # 3.行为:函数
    """
    关于self:
        a.self,自己,自身,表示当前对象
        b.哪个对象调用函数,其中的self则表示哪个对象
        c.self作为形参中一部分,不能省略,同时调用函数的时候,不需要手动给self传参
        d.当调用函数的时候,系统会自动把当前对象传参给self
        e.self其实并不是一个关键字,但是常用self,表示当前对象
    """
    def eat(self,sth):
        print(f"eating {sth}")
    def run(self):
        print('running',id(self))


# 二、访问类中成员
# 1.调用类中的函数,语法:对象.函数(实参)
per1 = Person()
print(f"per1的地址:{id(per1)}")
per1.run()
per1.eat("apple")

per2 = Person()
print(f"per2的地址:{id(per2)}")
per2.run()
per2.eat("food")

# 2.类的特征【变量/属性】
per = Person()
per.name = "张三"
per.age = 18
print(per.name,per.age)

"""
注意:
    a.类中的成员在类的里面不能直接访问,需要通过对象或类访问
    b.类的行为【函数】可以直接定义在类的内部,类的特征【变量】可以直接绑定
"""

3.2动态绑定属性和限制绑定

# 1.对象属性的动态绑定
class Person():
    def show(self):
        print(f"姓名:{self.name},爱好:{self.hobby},成绩:{self.score}")

# 语法:对象.属性 = 值,属性名自定义
per = Person()
per.name = "张三"
per.age = 18
per.hobby = "唱歌"
per.score = 100
print(per.name,per.age)
per.show()   # self--->per

# 注意1:给一个对象动态绑定属性,和其他对象没有任何关系
# per2 = Person()
# print(per2.name)

# 注意2:给多个对象绑定了重名的属性,一个对象的属性值发生改变,对其他对象的属性没有影响
per2 = Person()
per2.name = "李四"
per.name = "tom"
print(per2.name)

print("*" * 50)

# 2.限制对象属性的动态绑定
class Person():
    # __slots__ = ('字段1','字段2'.....),在元组中的字段表示允许动态绑定的字段
    # 注意:如果需要绑定的属性只有一个,则__slots__ = ('字段',)
    __slots__ = ("name",'hobby','score')
    def show(self):
        print(f"姓名:{self.name},爱好:{self.hobby},成绩:{self.score}")
per = Person()
per.name = "张三"
per.hobby = "唱歌"
per.score = 100
# per.age = 18  # AttributeError: 'Person' object has no attribute 'age'
per.show()

4.构造函数

先创建对象,然后使用直接赋值【动态绑定属性】方式给对象绑定属性,可以使用,但是代码比较繁杂,一般情况下,很多类倾向于将对象创建为有初始状态的,在类中可以定义一个函数,名称为__init__,该特殊的函数被称为构造函数,主要用于创建对象并将对象的数据做出初始化

强调:构造函数包括__new__和__init__

构造函数,也被称为构造器,指的是当创建对象的时候,被自动调用的函数

语法:
def __init__(self):
    函数体

# 1.未使用构造函数之前
class Person1():
    __slots__ = ('name','age')

p1 = Person1()
p1.name = 'aaa'
p1.age = 10

p2 = Person1()
p2.name = 'bbb'
p2.age = 15

p3 = Person1()
p3.name = 'ccc'
p3.age = 17

print("*" * 50)

# 2.构造函数的工作原理
"""
注意:
    a.如果类中未定义构造函数,当创建对象的时候,系统会自动调用构造函数
    b.构造函数包含:__new__()和__init__()
    c.p = Person().实际代码在执行的时候,p获取的是__new__的返回值
    d.如果将__new__显式的定义出来,则__new__的返回值必须是一个对象:super().__new__(cls)
    e.先调用__new__,然后调用__init__
    f.工作原理:先通过__new__创建一个对象,然后将该对象传参给__init__中的self,进行初始化
    g.__new__()和__init__()是在创建对象的过程中自动调用的,无需手动调用
"""
class Person2():
    __slots__ = ('name', 'age')
    # a.__new__:表示从无到有的过程,表示创建对象
    def __new__(cls, *args, **kwargs):
        print("new~~~~~")
        # super().__new__(cls)表示创建一个对象
        return super().__new__(cls)

    # b.__init__:表示初始化,初始化由__new__创建的对象
    def __init__(self,name,age):
        print("init~~~~~~")
        # 动态绑定属性
        self.name = name
        self.age = age

p21 = Person2('aaa',10)
print(p21)
print(p21.name,p21.age)

p22 = Person2('bbb',15)
print(p22)
print(p22.name,p22.age)

p23 = Person2('ccc',18)
print(p23)

# 3.实际使用
# 注意:在实际使用的时候,只需要定义构造函数中的__init__,当创建对象的时候,需要和__init__的参数匹配
class Person3():
    __slots__ = ('name', 'age')
    def __init__(self,name,age):
        self.name = name
        self.age = age

p31 = Person3('aaa',10)
print(p31)
print(p31.name,p31.age)

5.综合练习

# 需求:开学了,王老师让学生【小明,小花,小丽】做自我介绍
# 介绍姓名,年龄,爱好,来一段才艺展示
"""
分析:
    老师类:
        特征:姓名
        行为:让 .... 做自我介绍

    学生类:
        特征:姓名,年龄,爱好
        行为:做自我介绍,来一段才艺展示
"""
class Teacher():
    __slots__ = ("name",)

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

    # stu表示的是学生对象,并不是一个字符串
    def let_stu_introduce(self,stu):
        # self表示王老师的对象,stu表示的xiaoming的对象
        print(self.name + "让" + stu.name + "做自我介绍")

        # 让学生执行自己的行为
        stu.introduce()

        if stu.name == "小花":
            stu.sing()
        elif stu.name == "小丽":
            stu.dance()
        elif stu.name == "小明":
            stu.lie()

class Student():
    __slots__ = ("name","age","hobby")

    def __init__(self,name,age,hobby="学习"):
        self.name = name
        self.age = age
        self.hobby = hobby

    def introduce(self):
        print(f"大家好,我是{self.name},今年{self.age},爱好:{self.hobby}")

    def sing(self):   # 小花
        print("娘子~~~~啊哈")
    def dance(self):  # 小丽
        print("广场舞")
    def lie(self):  # 吹牛逼
        print("我家就有几千头羊,几千头牛~~~~~")

# 创建老师的对象
wang = Teacher("王老师")

# 创建学生的对象
xiaoming = Student("小明",8,"吹牛逼")
xiaohua = Student("小花",5,"唱歌")
xiaoli = Student(name="小丽",age=10,hobby="跳舞")

# 让老师执行自己的行为
wang.let_stu_introduce(xiaoming)
wang.let_stu_introduce(xiaohua)
wang.let_stu_introduce(xiaoli)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值