zoukankan      html  css  js  c++  java
  • 面向对象

    一、面向对象

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

    • 封装:将有共同的属性和方法封装到同一个类下面
    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根羽毛然后给其他人看
    '''
    
  • 相关阅读:
    Web开发中的服务器跳转与客户端跳转
    Linux设置程序开机自启动
    RedHat Linux6.4下安装apache服务
    FTP错误 [ftp: connect: No route to host] 解决方法
    虚拟机ping不通主机,但是主机可以ping通虚拟机(转载)
    工作中常用的Linux命令:mkdir命令
    工作中常用的Linux命令:crontab命令
    工作中常用的Linux命令:目录
    工作中常用的Linux命令:ipcs/ipcrm命令
    【CentOS】在Centos7 下无图形界面安装 Oracle11g
  • 原文地址:https://www.cnblogs.com/snailrunning/p/14356350.html
Copyright © 2011-2022 走看看