Python基础-------面向对象二

一、封装

什么是封装
在日常中封装指的是将我们的物品包裹起来,不让看到其内部,具有保护的功能。在程序设计中,封装(Encapsulation)是将类中的某些部分(某些属性或者方法)隐藏起来,对象不能直接使用隐藏起来的属性或者方法,具有保护功能。
私有属性封装
格式:_属性名
示例

# 封装:私有属性
# class Car():
#
#     def __init__(self, name, color):
#         self._name = name  # 私有属性
#         self.color = color
#
#     def run(self):
#         print('汽车开始跑起来了')
#
#     def dididi(self):
#         print('汽车鸣笛了')
#
#
# car = Car('法拉利', '红色')
# car._name = '中华田园犬'
# car.run()
# car.dididi()
# print(car._name)

运行结果

汽车开始跑起来了
汽车鸣笛了
中华田园犬

注意:
这种方法只是一种行业规定,表明这个属性不要被轻易更改,但是它还是能被更改
隐藏属性
格式:__属性名
示例

# 封装:隐藏属性
# class Car():
#
#     def __init__(self, name, color):
#         self.__name = name  # 隐藏属性 不可读的属性
#         self.color = color
#
#     def run(self):
#         print('汽车开始跑起来了')
#
#     def dididi(self):
#         print('汽车鸣笛了')
#
#
# car = Car('法拉利', '红色')
# car.__name = '中华田园犬'
# car.run()
# car.dididi()

运行结果

C:\Users\Lenovo\AppData\Local\Programs\Python\Python37\python.exe F:/桌面/day13/封装一.py
Traceback (most recent call last):
  File "F:/桌面/day13/封装一.py", line 60, in <module>
    print(car.__name)
AttributeError: 'Car' object has no attribute '__name'

进程已结束,退出代码为 1

可以看出程序报错无法访问
但是真的能完全无法访问吗?
其实隐藏属性只不过是Python自动为属性改了一个名字 --> _类名__属性名 例如

class Car():

    def __init__(self, name, color):
        self.__name = name  # 隐藏属性 不可读的属性
        self.color = color

    def run(self):
        print('汽车开始跑起来了')

    def dididi(self):
        print('汽车鸣笛了')


car = Car('法拉利', '红色')


print(car._Car__name)

运行结果

C:\Users\Lenovo\AppData\Local\Programs\Python\Python37\python.exe F:/桌面/day13/封装一.py
法拉利

进程已结束,退出代码为 0

我们也可以提供给一个getter()和setter()方法是外部可以访问到属性
• getter() 获取对象中指定的属性
• setter() 用来设置对象指定的属性
示例


class Car():

    def __init__(self, name, color):
        self._name = name  # 隐藏属性 不可读的属性
        self.color = color

    # getter方法  提供给你访问这个属性的方法
    def get_name(self):
        return self._name

    # setter方法  提供给你修改这个属性的方法
    def set_name(self, name):
        self._name = name

    def run(self):
        print('汽车开始跑起来了')

    def dididi(self):
        print('汽车鸣笛了')
car = Car('法拉利', '红色')
print(car.get_name())
car.set_name('玛莎拉蒂')
print(car.get_name())

运行结果

C:\Users\Lenovo\AppData\Local\Programs\Python\Python37\python.exe F:/桌面/day13/封装二.py
汽车开始跑起来了
汽车鸣笛了
法拉利
玛莎拉蒂

进程已结束,退出代码为 0

二、property装饰器

Python 还提供了 @property 装饰器。通过 @property 装饰器,可以直接通过方法名来访问方法,不需要在方法名后添加一对“()”小括号。
@property 的语法格式如下:

@property
def 方法名(self)
代码块

例如,定义一个矩形类,并定义用 @property 修饰的方法操作类中的 area 私有属性,代码如下:

class Rect:
   def __init__(self,area):
       self.__area = area
   @property
   def area(self):
       return self.__area
rect = Rect(30)
#直接通过方法名来访问 area 方法
print("矩形的面积是:",rect.area)

上面程序中,使用 @property 修饰了 area() 方法,这样就使得该方法变成了 area 属性的 getter 方法。需要注意的是,如果类中只包含该方法,那么 area 属性将是一个只读属性。
也就是说,在使用 Rect 类时,无法对 area 属性重新赋值
而要想实现修改 area 属性的值,还需要为 area 属性添加 setter 方法,就需要用到 setter 装饰器,它的语法格式如下:

@方法名.setter
def 方法名(self, value):
代码块

例如,为 Rect 类中的 area 方法添加 setter 方法,代码如下:

@area.setter
def area(self, value):
    self.__area = value

这样,area 属性就有了 getter 和 setter 方法,该属性就变成了具有读写功能的属性。
除此之外,还可以使用 deleter 装饰器来删除指定属性,其语法格式为:

@方法名.deleter
def 方法名(self):
代码块

例如,在 Rect 类中,给 area() 方法添加 deleter 方法,实现代码如下:

@area.deleter
def area(self):
    self.__area = 0

然后运行如下代码:

del rect.area
print("删除后的area值为:",rect.area)

运行结果为:

删除后的area值为: 0

三、继承

什么是继承?
让子类直接拥有父类的属性和方法的过程就是继承
父类 - 被继承者(又叫超类)
子类 - 继承者
怎么继承

"""
class 类名(父类1,父类2,...):
    类的说明文档
    类的内容
    
注意: 默认情况下,定义的类继承自 object
"""


class Person:
    num = 61

    def __init__(self):
        print('Person中init')
        self.name = '小明'
        self.age = 18
        self.gender = '男'
        self.__sex = '女'

    def eat(self):
        print(f'Person:{self.name}在吃饭')

    @classmethod
    def show_num(cls):
        print(f'人类的数量:{cls.num}')

    @staticmethod
    def func1():
        print('人类破坏环境!')


# 让 Student(子类) 继承 Person(父类)
class Student(Person):
    pass


# 继承的时候子类可以直接拥有父类所有的属性和方法
print(Student.num)
stu = Student()
print(stu.name, stu.age, stu.gender)
stu.eat()
Student.show_num()
Student.func1()
print(stu.__dict__)

在子类中添加内容

1.在子类中添加类属性和方法
类属性和方法的添加不会因为继承而收到任何影响
2.添加对象属性
对象属性是怎么被继承:继承的时候因为init方法被继承,间接继承了对象属性

在子类的__init__方法中通过 super()去调用父类的__init__方法 

类中的方法的调用过程(重要)
通过类或者对象在调用方法的时候,会先看当前类中有没有这个方法,如果有就直接调用自己类中的方法;没有就看父类中有没有定义这个方法,如果父类定义了就调用父类的;父类没有定义,就看父类的父类中有没有定义…以此类推,如果object 中没有定义才会报错!

class Teacher(Person):
    title = '老师'

    def __init__(self):
        # 调用父类的init方法
        super().__init__()
        self.school = '千锋'
        self.subject = 'Python'
        self.tea_id = '001'

    def attend_class(self):
        print('老师上课')

    def eat(self):
        super().eat()
        print(f'老师在吃饭')


print(Teacher.num, Teacher.title)
t1 = Teacher()
t1.attend_class()

print(t1.school, t1.subject, t1.tea_id)
print(t1.name)

t1.eat()

四、多继承

class Animal:
    num = 10

    def __init__(self, age, gender):
        self.age = age
        self.gender = gender

    def eat(self):
        print('动物需要吃东西')


class Fly:
    name = '飞行器'

    def __init__(self, height, time):
        self.height = height
        self.time = time

    def stop(self):
        self.height = 0
        print('停止飞行')


class Bird(Animal, Fly):
    pass


b1 = Bird(2, '雌')

# 两个父类的类属性都可以继承
print(Bird.num)
print(Fly.name)

# 对象属性只会继承第一个父类的
print(b1.age, b1.gender)
# print(b1.height, b1.time)    # AttributeError: 'Bird' object has no attribute 'height'

# 两个父类的不同方法都可以继承
b1.eat()
b1.stop()

五、方法的重写

子类和父类中拥有方法名相同的方法,说明子类重写了父类的方法

重写的作用:父类中已经有了这个方法,但子类想修改里面的内容,直接修改父类是不好的,就需要用到重写
例如:

class Animal:
 def eat(self):
 print("---吃-----")
 def drink(self):
 print("----喝-----")
 def sleep(self):
 print("----睡觉-----")
class Dog(Animal):
 def bark(self):
 print("---汪汪叫----")
  
class Xiaotq(Dog):
 def fly(self):
 print("----飞-----")
 def bark(self):
 print("----狂叫-----")
  
xiaotq = Xiaotq()
xiaotq.fly()
xiaotq.bark()
xiaotq.eat()

super方法

super这个方法的使用时建立在两个基础之上的

  1. 必须要有父类的继承
  2. 必须要有方法的重写
    例如:
class A(object):
    def sleep(self):
        print(11111)


class Animal(A):  # 括号中没写,默认继承object

    def sleep(self):  # 房地产
        print('动物会睡觉')

    def run(self):
        print('动物会跑')


class Dog(Animal):

    def sleep(self):  # 电竞
        print('狗会睡觉')
        # super的作用: 将被覆盖了的父类方法,重新调用
        super().sleep() 
dog = Dog()
dog.run()
dog.sleep()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哥哥的梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值