Python——面向对象

面向对象

一. 理解面向对象

面向对象是一种抽象化的编程思想,很多编程语言中都有的一种思想。

面向对象就是将编程当成是一个事物,对外界来说,事物是直接使用的,不用去管他内部的情况。而编程就是设置事物能够做什么事。

在面向对象编程过程中,有两个重要组成部分: 对象

: 比如是制造洗衣机时要用到的图纸

对象 : 比如是就是用图纸造出来的洗衣机

类是对一系列具有相同 特征 和 行为 的事物的统称

类和对象的关系:用类去创建一个对象。 那么对象就有自己的特征 和 行为

  • 特征即是属性
    比如 : 年龄 相貌, 地域 ,身高 体重
  • 行为即是方法
    比如 : 飞 ,洗 打 烤 ,跑 ,看

类和对象的关系 :对象是由类创造出来的!

注意:先有类,再有对象。

二. 面向对象实现方法

2.1 定义类

Python2中类分为:经典类 和 新式类

  • 新式类
class 类名():
    代码
    ......
    
# 类的写法 
class Washer():
	pass

注意:类名要满足标识符命名规则,注意,首字母大写!,同时遵循 大驼峰命名习惯 。

  • 经典类

不由任意内置类型派生出的类,称之为经典类,现在几乎很少用,但得知道

class 类名:
    代码
    ......
    
class Washer:
    pass

2.2 创建对象

对象又名实例。

  • 语法
对象名 = 类名()
# 创建对象
class Washer():
	pass

haier1 = Washer()

# <__main__.Washer object at 0x0000018B7B224240>
print(haier1)

注意:创建对象的过程也叫实例化对象。

2.3 对象的属性 __init__()

__init__()方法的作用:初始化对象。

通俗一点讲 : __init()__里面就是对象属性的"聚集地"

对象属性既可以在类外面添加和获取,也能在类里面添加和获取。

class Washer():  # 定义初始化功能的函数    
    def __init__(self):  # 添加实例属性        
        self.width = 500  #  宽度是 500 
        self.height = 800  #  高度 是 800 
     
haier1 = Washer()
print(haier1.width)


class Washer():  # 定义初始化功能的函数
    def __init__(self, color):  # 添加实例属性
        self.width = 500  # 宽度是 500
        self.height = 800  # 高度 是 800
        self.yanse = color


haier1 = Washer('yellow')
print(haier1.yanse)

注意:

  • __init__()方法,在创建一个对象时默认被调用,不需要手动调用
  • __init__(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去。

2.4 self参数

self指的是调用该函数的对象。

class Washer():  # 定义初始化功能的函数
    def __init__(self):  # 添加实例属性
        self.width = 500  # 宽度是 500
        self.height = 800  # 高度 是 800
        # print(self)


haier1 = Washer()
print(haier1.width)  # 500


# 此时会有两个疑惑 ?
# 1 : __init__  是一个函数 ,但是为什么没看到调用 ?
# 2 : 函数里面有参数 self ,为什么没看到传参 ?


# 首先看看 self是什么 ? 此时会发现,self 和 haier1 是一样的 所以  ,self就是那个对象 
print(haier1)  # <__main__.Washer object at 0x0000000000437490>

haier2 = Washer()
# <__main__.Washer object at 0x0000022005857EF0>
print(haier2)

2.5 实例属性与类属性

Python在广义上的属性有两种:类属性实例属性

实例属性

一般是在构造函数__init__()中定义的,定义必须使用self前缀,只能通过对象名来访问

class Dog():
    def __init__(self):
        self.age = 5

    def info_print(self):
        print(self.age)


wangcai = Dog()
print(wangcai.age)  # 5
# print(Dog.age)  # 报错:实例属性不能通过类访问
wangcai.info_print()  # 5

类属性

  • 类属性就是 类对象 所拥有的属性,它被 该类的所有实例对象 所共有
  • 类属性可以使用 类对象实例对象 访问。
  • 实例属性只能是对象来访问,类对象不可以
  • 类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了一个实例属性。
class Dog():
    tooth = 10


wangcai = Dog()
xiaohei = Dog()

print(Dog.tooth)  # 10
print(wangcai.tooth)  # 10
print(xiaohei.tooth)  # 10


class Dog(object):
    tooth = 10


wangcai = Dog()
xiaohei = Dog()

# 修改类属性
Dog.tooth = 12
print(Dog.tooth)  # 12

# 不能通过对象修改属性,如果这样操作,实则是创建了一个实例属性
wangcai.tooth = 20
print(Dog.tooth)  # 12
print(wangcai.tooth)  # 20
print(xiaohei.tooth)  # 12

类属性的优点

  • 记录的某项数据 始终保持一致时,则定义类属性。
  • 实例属性 要求 每个对象 为其 单独开辟一份内存空间 来记录数据,而 类属性 为全类所共有 ,仅占用一份内存,更加节省内存空间。

2.6 保护机制

私有成员:为了数据封装和保密而设的属性,一般只能在类的成员方法中使用访问。如果属性名以两个下划线开头’__'则表示是私有属性。

公有成员:可以公开使用,既可以在内部进行访问,也可以在外部程序中使用。

保护成员:只有类对象和子类对象能访问这些成员,如果属性名以一个下划线开头’_'则表示是私有属性。

class A:
	def __init__(self,value1=0,value2=0):
		self._value1=value1	#定义保护成员
		self.__value2=value2	#定义私有成员
	def setValue(self,value1,value2):
		self.__value1=value1
		self.__value2=value2
	def show(self):
		print(self._value1)
		print(self.__value2)
a=A()
a._value1

a.__value2	#	报错

2.7 对象的方法

class Washer():  # 定义初始化功能的函数
    def __init__(self):  # 添加实例属性
        self.width = 500  # 宽度是 500
        self.height = 800  # 高度 是 800
        # print(self)
    def wash(self):  #  实例方法
        print(f'我是{self}的方法,这个必须用对象(实例)调用我才能运行')

    def broke(self):
        print('经过很多年以后,被使坏了.')


haier1 = Washer()
print(haier1.width)  # 500
haier1.wash()  # 调用实例方法
haier1.broke()

三. 魔法方法

3.1 __str__()

当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了__str__方法,那么就会打印从在这个方法中 return 的数据。

class Washer():    
    def __init__(self, width, height):        
        self.width = width        
        self.height = height    
    def __str__(self):        
        return '这是海尔洗衣机的说明书'  # 必须得是字符串形式 
haier1 = Washer(10, 20)# 这是海尔洗衣机的说明书
print(haier1)

四. 继承机制

继承是为了代码复用和设计复用而设计的,在继承关系中,已有的、设计好的类称为父类或者基类,新设计的类叫做子类或者派生类,派生类可以继承基类的公有成员,但不能继承私有成员。

4.1 单继承

故事主线:一个烤冷面老师傅,在烤冷面界摸爬滚打多年,研发了一套精湛的摊烤冷面的技术。师父要把这套技术传授给他的唯一的最得意的徒弟。

分析:徒弟是不是要继承师父的所有技术?

# 1. 师父类
class Master():
    def __init__(self):
        self.kongfu = '[古法烤冷面配方]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作烤冷面')

        
# 2. 徒弟类
class Prentice(Master):
    pass


# 3. 创建对象daqiu
daqiu = Prentice()
# 4. 对象访问实例属性
print(daqiu.kongfu)
# 5. 对象调用实例方法
daqiu.make_cake()

4.2 多继承

同时继承多个父类,如果父类中有相同的方法名,而在子类中使用时没有指定父类名,则会按继承的顺序从左到右顺序进行搜索。

class SchoolA():


    def make_cake(self):
        print('制作schoolA煎饼果子')

    def make_noodles(self):
        print('制作schoolA烤冷面')


# 创建学校类
class SchoolB():


    def make_cake(self):
        print('制作schoolB的煎饼果子')


class Prentice(SchoolB, SchoolA):
    pass


daqiu = Prentice()
daqiu.make_cake()	#输出SchoolB的make_cake
daqiu.make_noodles()

4.3 重载

即子类重写父类同名方法

class SchoolA(object):


    def make_cake(self):
        print('制作SchoolA煎饼果子')


class SchoolB(object):


    def make_cake(self):
        print('制作SchoolB煎饼果子')


# 独创配方
class Prentice(SchoolB, SchoolA):
    def __init__(self):
        self.kongfu = '[独创煎饼果子配方]'

    def make_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')


daqiu = Prentice()
print(daqiu.kongfu)
daqiu.make_cake()

print(Prentice.__mro__)  # 查看继承顺序

4.4 小难题

class Parent(object):
    x = 1
class Child1(Parent):
    pass
class Child2(Parent):
    pass
print(Parent.x, Child1.x, Child2.x)
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
Parent.x = 3
print(Parent.x, Child1.x, Child2.x)


1 1 1
1 2 1
3 2 3


#Parent.x = 3 父类重新定义了x    Parent.x=3

#child1自己有X 故   child1.x = 2

#child2并没有X  执行父类的x   child.x = 3

五. 综合应用—烤地瓜

5.1 需求

需求主线

被烤的时间和对应的地瓜状态:

  • 0-3分钟:生的

  • 3-5分钟:半生不熟

  • 5-8分钟:熟的

  • 超过8分钟:烤糊了

添加的调料

用户可以按自己的意愿添加调料

5.2 步骤分析

需求涉及一个事物: 地瓜,故案例涉及一个类:地瓜类。

(1) 定义类
  • 地瓜的属性

    • 被烤的时间
    • 地瓜的状态
    • 添加的调料
  • 地瓜的方法

    • 被烤
      • 用户根据意愿设定每次烤地瓜的时间
      • 判断地瓜被烤的总时间是在哪个区间,修改地瓜状态
    • 添加调料
      • 用户根据意愿设定添加的调料
      • 将用户添加的调料存储
  • 显示对象信息

(2) 创建对象,调用相关实例方法

5.3 代码实现

(1) 定义类
  • 地瓜属性
    • 定义地瓜初始化属性,后期根据程序推进更新实例属性
class SweetPotato():    
    def __init__(self):        
        # 被烤的时间        
        self.cook_time = 0        
        # 地瓜的状态        
        self.cook_static = '生的'        
        # 调料列表        
        self.condiments = []
(2) 定义烤地瓜方法
    def cook(self, time):
        """烤地瓜的方法"""
        self.cook_time += time
        if 0 <= self.cook_time < 3:
            self.cook_static = '生的'
        elif 3 <= self.cook_time < 5:
            self.cook_static = '半生不熟'
        elif 5 <= self.cook_time < 8:
            self.cook_static = '熟了'
        elif self.cook_time >= 8:
            self.cook_static = '烤糊了'
(3) 书写str魔法方法,用于输出对象状态
    def __str__(self):
        return f'这个地瓜烤了{self.cook_time}分钟, 状态是{self.cook_static}'
(4) 创建对象,测试实例属性和实例方法
digua1 = SweetPotato()
print(digua1)
digua1.cook(2)
print(digua1)
(5) 定义添加调料方法,并调用该实例方法
    def add_condiments(self, condiment):
        """添加调料"""

        self.condiments.append(condiment)

    def __str__(self):
        return f'这个地瓜烤了{self.cook_time}分钟, 状态是{self.cook_static}, 添加的调料有{self.condiments}'

5.4 代码总览

class SweetPotato():
    def __init__(self):
        # 被烤的时间
        self.cook_time = 0
        # 地瓜的状态
        self.cook_static = '生的'
        # 调料列表
        self.condiments = []
    def cook(self, time):
        """烤地瓜的方法"""
        self.cook_time += time
        if 0 <= self.cook_time < 3:
            self.cook_static = '生的'
        elif 3 <= self.cook_time < 5:
            self.cook_static = '半生不熟'
        elif 5 <= self.cook_time < 8:
            self.cook_static = '熟了'
        elif self.cook_time >= 8:
            self.cook_static = '烤糊了'


    def add_condiments(self, condiment):
        """添加调料"""

        self.condiments.append(condiment)

    def __str__(self):
        return f'这个地瓜烤了{self.cook_time}分钟, 状态是{self.cook_static}, 添加的调料有{self.condiments}'

digua1 = SweetPotato()
print(digua1)
digua1.cook(2)
digua1.add_condiments('酱油')
print(digua1)
digua1.cook(2)
digua1.add_condiments('辣椒面儿')
print(digua1)
digua1.cook(2)
print(digua1)
digua1.cook(2)
print(digua1)
digua2 = SweetPotato()
digua2.cook(3)
print(digua2)

六. 综合应用—搬家具

5.1 需求

将小于房子剩余面积的家具摆放到房子中

5.2 步骤分析

需求涉及两个事物:房子 和 家具,故被案例涉及两个类:房子类 和 家具类。

(1) 定义类
  • 房子类

    • 实例属性
      • 房子地理位置
      • 房子占地面积
      • 房子剩余面积
      • 房子内家具列表
    • 实例方法
      • 容纳家具
    • 显示房屋信息
  • 家具类

    • 家具名称
    • 家具占地面积
(2) 创建对象并调用相关方法

5.3 代码实现

(1) 定义类

家具类

class Furniture():
    def __init__(self, name, area):
        # 家具名字
        self.name = name
        # 家具占地面积
        self.area = area

房子类

class Home():
    def __init__(self, address, area):
        # 地理位置        
        self.address = address
        # 房屋面积        
        self.area = area
        # 剩余面积        
        self.free_area = area
        # 家具列表        
        self.furniture = []

    def __str__(self):
        return f'房子坐落于{self.address}, 占地面积{self.area}, 剩余面积{self.free_area}, 家具有{self.furniture}'

    def add_furniture(self, item):
        """容纳家具"""
        if self.free_area >= item.area:
            self.furniture.append(item.name)
            # 家具搬入后,房屋剩余面积 = 之前剩余面积 - 该家具面积            
            self.free_area -= item.area
        else:
            print('家具太大,剩余面积不足,无法容纳')
(3) 创建对象并调用实例属性和方法
bed = Furniture('双人床', 6)
jia1 = Home('北京', 1200)
print(jia1)
jia1.add_furniture(bed)
print(jia1)
sofa = Furniture('沙发', 10)
jia1.add_furniture(sofa)
print(jia1)
ball = Furniture('篮球场', 1500)
jia1.add_furniture(ball)
print(jia1)

5.4 代码总览

class Furniture():
    def __init__(self, name, area):
        # 家具名字
        self.name = name
        # 家具占地面积
        self.area = area


class Home():
    def __init__(self, address, area):
        # 地理位置
        self.address = address
        # 房屋面积
        self.area = area
        # 剩余面积
        self.free_area = area
        # 家具列表
        self.furniture = []

    def __str__(self):
        return f'房子坐落于{self.address}, 占地面积{self.area}, 剩余面积{self.free_area}, 家具有{self.furniture}'

    def add_furniture(self, item):
        """容纳家具"""
        if self.free_area >= item.area:
            self.furniture.append(item.name)
            # 家具搬入后,房屋剩余面积 = 之前剩余面积 - 该家具面积
            self.free_area -= item.area
        else:
            print('家具太大,剩余面积不足,无法容纳')
bed = Furniture('双人床', 6)
jia1 = Home('北京', 1200)
print(jia1)
jia1.add_furniture(bed)
print(jia1)
sofa = Furniture('沙发', 10)
jia1.add_furniture(sofa)
print(jia1)
ball = Furniture('篮球场', 1500)
jia1.add_furniture(ball)
print(jia1)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值