面向对象

一、面向对象

面向对象是一种编程,以类的眼光来看待事物,将共同的属性和方法的事物封装到同一个类下面

  • 封装:将有共同的属性和方法封装到同一个类下面
  1. 创建类和对象会分别创建二者的名称空间,我们能用类名.属性或发放,对象名.属性或方法的方式去访问里面的名字(属性或方法)
  2. 类中把某些属性和方法隐藏起来(定义为私有),只有类内部使用、外部无法访问,或留下少量接口供外部访问
  • 继承:将多个类的共同属性和方法封装到一个父类下面,然后用这些类来继承这个类的属性和方法
  • 多态:基类的同一个方法在不同的派生类中有着不同的功能

二、封装的那些事

隐藏属性(私有属性)

类里的属性或方法前加上两个下划线(__),代表属性或方法被隐藏,

class A:
    __x = 1  # _A__x=1

    def __init__(self, name):
        self.__name = name  # self._A__name=name

    def __foo(self):  # def _A__foo(self):
        print('run foo')

    def bar(self):
        self.__foo()  # self._A__foo()
        print('from bar')


print(A.__dict__)
'''
{'__module__': '__main__', '_A__x': 1, '__init__': <function A.__init__ at 0x7fa2ed7c76a8>, 
'_A__foo': <function A.__foo at 0x7fa2eeac7598>, 'bar': <function A.bar at 0x7fa2eeac7510>, 
'__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
'''

python中的“私有”,实际上是在定义类的时候把“名字”给变形了

这种变形的特点:

  1. 在类外部无法直接obj.__AttrName
  2. 在类内部是可以直接使用:obj.__AttrName
  3. 子类无法覆盖父类__开头的属性

直接访问隐藏属性

A = A('haha')
print(A._A__x)  # 1
A._A__foo()  # run foo
  1. 通过变形后的名字访问属性
  2. 通过变形后的名字调用方法

问题:隐藏属性可以修改吗?

python没有做强制限制,实际上允许你修改,但不建议你修改,原本就是让你隐藏起来,你还故意这么操作。

封装数据属性的意义:明确的区分内外,控制外部对隐藏的属性的操作行为。

三、继承的那些事

  • 继承的实现方式主要有两类:

    1. 实现继承:使用基类的属性和方法无需额外编码的能力
    2. 接口继承:仅使用属性和方法的名字,但是子类必须提供实现的能力(子类重构父类的方法)
  • python有两种类:

    1. 经典类:不继承object的类,object类里提供__str__等内置方法
    2. 新式类:继承object的类
    3. python3的类默认继承object,为新式类
    4. python2的类默认不继承object,为经典类,若主动继承object类,则为新式类
  • 继承分为单继承和多继承

    1. python是支持多继承,(类名__.bases__ 查看当前类的父类)
    2. 继承的顺序可使用__mro__顺序查看
    3. 经典类继承顺序按深度优先查找
    4. 新式类继承查找顺序按广度优先查找
  • 继承的方法查找:对象可以调用自己本类和父类的所有方法和属性, 先调用自己的 、自己没有 才调父类的。谁(对象)调用方法,方法中的 self 就指向谁

  • 子类可以使用super(). 来使用父类的方法

实现继承

class Hero:
    x = 3

    def __init__(self, nickname, life_value, aggresivity):
        self.nickname = nickname
        self.life_value = life_value
        self.aggresivity = aggresivity

    def attack(self, enemy):
        enemy.life_value -= self.aggresivity


class Garen(Hero):
    pass


class Riven(Hero):
    pass


g1 = Garen('德玛西亚', 29, 30)

接口继承(使用抽象类)

import abc


class Animal(metaclass=abc.ABCMeta):  # 只能被继承,不能被实例化
    all_type = 'animal'

    @abc.abstractmethod
    def run(self):
        pass

    @abc.abstractmethod
    def eat(self):
        pass


# animal=Animal()  # TypeError: Can't instantiate abstract class Animal with abstract methods eat, run


class People(Animal):
    def run(self):
        print('people is running')

    def eat(self):
        print('people is eating')


class Pig(Animal):
    def run(self):
        print('people is walking')

    def eat(self):
        print('people is eating')


class Dog(Animal):
    def run(self):
        print('people is walking')

    def eat(self):
        print('people is eating')


peo1 = People()
pig1 = Pig()
dog1 = Dog()

四、多态的那些事

基类的同一个方法在不同的派生类中有着不同的功能

# 多态:同一类事物的多种形态
import abc


class Animal(metaclass=abc.ABCMeta):  # 同一类事物:动物
    @abc.abstractmethod
    def talk(self):
        pass


class People(Animal):  # 动物的形态之一:人
    def talk(self):
        print('say hello')


class Dog(Animal):  # 动物的形态之二:狗
    def talk(self):
        print('say wangwang')


class Pig(Animal):  # 动物的形态之三:猪
    def talk(self):
        print('say aoao')


class Cat(Animal):
    def talk(self):
        print('say miamiao')


# 多态性:指的是可以在不考虑对象的类型的情况下而直接使用对象
peo1 = People()
dog1 = Dog()
pig1 = Pig()
cat1 = Cat()

鸭子类型

当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子

在程序设计中是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定。

鸭子类型在不使用继承的情况下使用了多态

class Duck:
    def quack(self):
        print("这鸭子正在嘎嘎叫")

    def feathers(self):
        print("这鸭子拥有白色和灰色的羽毛")


class Person:
    def quack(self):
        print("这人正在模仿鸭子")

    def feathers(self):
        print("这人在地上拿起1根羽毛然后给其他人看")


def in_the_forest(duck):  # in_the_forest函数而言,对象是一个鸭子
    duck.quack()
    duck.feathers()


def game():
    donald = Duck()
    john = Person()
    in_the_forest(donald)
    in_the_forest(john)


game()
'''
这鸭子正在嘎嘎叫
这鸭子拥有白色和灰色的羽毛
这人正在模仿鸭子
这人在地上拿起1根羽毛然后给其他人看
'''
posted @ 2021-02-01 14:13  深圳-逸遥  阅读(73)  评论(0编辑  收藏  举报