python-面向对象

概念

类、对象

"""
面向对象
"""


class Person(object):
    def __init__(self, name, age):
        # 初始化
        self.name = name
        self.age = age

    def eat(self, food):
        pass


p = Person('sunchangheng', 26)  # 实例化

print(p.age)
print(p.__dict__)  # 查看对象的所有属性和值
print(Person.__dict__)  # 查看类的所有方法 

相当于模板

查看类中的方法类名.__dict__

对象

相当于同通过模板创造出来的实实在在的东西 

  1、查看所有属性和值对象名.__dict__

  2、单独查看某个属性:对象名.某个属性

实例化、实例

实例化

从类中创造一个类出来的过程

对象被实例化的时候,创建了一个类对象指针,类对象指针指向类命名空间

实例

从类里创建出来的对象即成为实例

self

  • 对象就是一个self,self指向实例好的对象

  • self是一个可以存储很多属性的大字典

  • self拥有的属性都是属于对象的

属性

创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性

而类有两种属性:静态属性和动态属性

  • 静态属性:直接在类中定义的变量
  • 动态属性:实例化对象时创建的属性

特性

 继承

一个类可以被多个类继承

一个类可以继承多个父类  -->python里

"""主动调用父类的方法"""


class BasePerson(object):

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

    def walk(self):
        print('base walk')

    def talk(self):
        print('base talk')


class SuperMan(BasePerson):
    def __init__(self, age, gender):
        # 继承父类的属性
        super(SuperMan, self).__init__(age, gender)  # 方式一
        # BasePerson.__init__(self, age, gender)    # 方式二

    def walk(self):
        # BasePerson.walk(self)   # 方式一
        super(SuperMan, self).walk()  # 方式二
        print('superman walk')

    def talk(self):
        # BasePerson.talk(self)
        print('superman talk')


super_man = SuperMan('18', '1')
super_man.walk()
print(super_man.age)

单继承

派生属性:父类中没有的属性,在子类中出现

派生方法:父类中没有的方法,在子类中出现

只要子类的对象调用子类中有的名字(方法),一定先用子类的,子类中没有才找父类的,如果父类也没有就报错

如果子类和父类都有的名字(方法),先用 子类的,如果还想调用父类的,需要自己传self参数

调用父类的方法

  父类名.方法(对象)

  super(子类,对象).方法名()  # super方法只在python3中存在

继承父类的属性

在子类的init方法下

  其实就是利用上面的主动调用父类的__init__方法实现的继承父类属性

注意:super的本质不是单纯找父类,而是根据调用者的节点位置的广度优先顺序来的

多继承

接口隔离原则:使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口。

Python 2.x中默认都是经典类,只有显式继承了object才是新式类
Python 3.x中默认都是新式类,不必显式的继承object


旧式类和新式类默认按照: 深度搜索

当遇到广度和深度两个选择时(例如钻石继承)
  新式类    广度优先搜索,且有 __mro__方法(记录新式类中的继承顺序)
  旧式类    深度优先搜索。

多态

  • 不依赖父类的情况下实现两个相识的同名方法

  • 鸭子类型:如果两个类刚好相似,并不产生父类-子类的关系,而是鸭子类型

  • list、tuple这种类似同名方法,是通过写代码的时候约束的,而不是通过父类约束

  • 优点:松耦合,每个相似的类之间都没有影响

  • 缺点:太随意,只能靠自觉去怎么定义一个类似的方法

封装

代码的保护,面向对象的思想本身就是一种

只让对象自己内部能调用类中的方法、属性

属性和方法都藏起来,不让你看见

父类中的所有私有属性不能被子类调用

调用

  • 内部使用:对象名.__私有属性名
"""
私有属性
"""


class SunChangHeng(object):
    country = 'china'

    def __init__(self, age, name):
        self.__age = age  # 私有属性,只可以在对象内部使用
        self.name = name

    def get_age(self):
        print('你的私有年龄是: ' % self.__age)


sun = SunChangHeng(19, 'sun')
print(sun.name)
# print(sun.__age)    # 访问不到

私有

  对象的属性

  类中的方法

  类中的静态属性

组合

一个对象的属性值是另一类的对象

"""
组合使用
"""


class Birth(object):
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day


class Person(object):
    def __init__(self, name, birthday):
        self.name = name
        self.birthday = birthday


bir = Birth(1993, 8, 21)
sun = Person('sunchangheng', bir)
print(sun.birthday.__dict__)

方法

类方法

@classmethod装饰

把一个方法变成一个类方法,这个方法就直接可以被类调用,不需要依托对象

需要传cls参数

当这个方法只涉及静态属性的时候,就应该使用classmethod来装饰这个方法

"""
类方法
"""


class Goods(object):
    __discount = 0.8

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

    @property
    def price(self):
        return self.__price * Goods.__discount

    @classmethod
    def set_discount(cls, discount):
        cls.__discount = discount


iphone4 = Goods('apple iphone4', 4999)
print(iphone4.price)
Goods.set_discount(0.9)
print(iphone4.price)    

类静态方法

@staticmethod装饰

将类中的一个方法变成一个普通函数(静态方法),但还是要通过类名.方法()调用

如果一个函数既和对象没有关系,也和类没有关系,那么就用staticmethod装饰这个函数

"""
将类中的一个方法变成一个普通函数(静态方法),但还是要通过类名.方法()调用
"""


class BaseMath(object):
    """
    工具包
    """

    @staticmethod
    def add(a, b):
        return a + b

    @staticmethod
    def reduce(a, b):
        return a - b

    @staticmethod
    def multiply(a, b):
        return a * b

    @staticmethod
    def div(a, b):
        return a / b


print(BaseMath.add(10, 8))
print(BaseMath.reduce(10, 8))
print(BaseMath.multiply(10, 8))
print(BaseMath.div(10, 8))

类计算属性

@property装饰

将类中的一个方法伪装成一个属性

配合setter、deleter使用

"""
将类中的一个方法伪装成一个属性
计算属性
"""

from math import pi


class Circle(object):
    def __init__(self, r):
        self.r = r

    @property
    def perimeter(self):
        return 2 * pi * self.r

    @property
    def area(self):
        return 2 * pi * self.r ** 2


c1 = Circle(8)
print(c1.perimeter)
print(c1.area)
原文地址:https://www.cnblogs.com/sunch/p/9460466.html