python面向对象编程基础

目录

  属性与方法

  继承机制 

  抽象类

  多重继承

  @property装饰器

  多态

  运算符重载

    面向对象程序设计(Object Oriented Programming,OOP)主要针对大型软件设计而提出,是得软件设计更加灵活,能够很好地支持代码复用和设计复用,并且是的代码具有更好的可读性和可扩展性。

  Python中对象的概念很广泛,Python中的一切内容都可以称为对象。

  Python使用class关键字来定义类,class关键字之后是一个空格,然后是类的名字,再然后是一个冒号,最后换行并定义类的内部实现

  定义了类之后。可以用来实例化对象,并通过“对象名.成员”的方式来访问其中的数据成员或成员方法。

  在Python中,可以使用内置方法isinstance()来测试一个对象是否为某个类的实例。

  Python提供了一个关键字“pass”,类似于空语句,可以用再类和函数的定义中或者选择结构中。当咱叔没有确定如何实现功能,或者为以后的软件升级预留空间,或者其他类型功能时,可以使用改关键字来“占位”

  类的所有实例方法都必须至少有一个名为sel的参数,并且必须是方法的第一形参(如果多个形参的话),self参数代表当前对象(当前正在调用方法的对象)

  在类的实例方法中访问实例属性时需要以self为前缀,但在外部通过对象名调用对象方法时并不需要传递这个参数。

一、属性

  Python的属性分为实例属性和类属性

  实例属性是在类内部定义的属性,可以被类中的所有实例共享

  注意:如果属性的名字以两个下划线开始,就表示私有属性(方法也一样)不可以调用,一个下划线,也表示私有属性,外部可以调用

class Businessman:
    def __init__(self,name,age,money):
        self.name = name
        self.age = age
        self.__money = money # __money为私有属性,只能在当前类中访问该私有属性
    def getMoney(self):
        return self.__money     # 可以通过类的内部访问私有属性
bs = Businessman("马云",55,200)
print("实例化对象的名字:",bs.name)
print("实例化对象的年龄:",bs.age)
#print("实例化对象的财产:",bs.__money)  #报错
print(bs._Businessman__money)   # 可以通过  " _类名__实例化属性名"的方式访问私有属性
print("该商人的财产是:",bs.getMoney())
私有属性
class Person:
    count = 0 # 类属性
    def __init__(self,name,age,sex):
        self.name = name   # name实例属性
        self.age = age   # age实例属性
        self.sex = sex    # sex实例属性
    def say(self):
        print("我叫",self.name,",今年",self.age,"岁了,性别:",self.sex)

per1 = Person("张三",20,"")   # 实例化per1对象
per2 = Person("李红",22,"")   # 实例化per2对象
per1.say()
per2.say()
Person.count = Person.count + 10 # 给类属性加10
print("改变count类属性之后的值:",Person.count)
print("通过实例化对象访问count类属性:",per1.count)
per1.count = per1.count + 10  # 相当于对per1对象的count实例化属性赋值(动态添加了一个count实例化属性)
print("给per1实例化对象添加count实例属性之后的值:",per1.count)
类属性
class Worker:
    # 初始化方法
    def __init__(self,name,age):
        print("一个对象实例化了...")
        self.name = name  # 给name属性赋值,self.name说明name为该对象的一个实例属性
        self.age = age # 给age属性赋值,self.age说明age为该对象的一个实例属性
    def repair(self):
        print("名字叫",self.name,"的电工,年龄为:",self.age,"正在修电灯...")

w = Worker("tom",20)   # 实例化对象,完成实例化对象之后会自动去调用__init__(self,name,age)方法
w.repair()

二、方法

  __init__()方法:构造方法,用来初始化新创建的对象

  __str__(self)方法:返回一个字符串,实现了__str(self)方法后,可以直接使用print语句输出对象,也可以通过str()触发__str__(self)的执行

class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    # 实现了__str__(self)方法后,直接打印对象或使用str( )函数转换对象为字符串,都会触发该__str__(self)方法
    def __str__(self):
        return "我叫" + self.name + ";今年" + str(self.age) +"岁了"
per = Person("tom",20)
print(per)
print(str(per))

 

三、静态方法与类方法

  Python使用函数staticmethod()或@staticmethod修饰器把普通的函数转化为静态方法

  类方法是将类本身作为操作对象的方法。类方法可以使用函数classmethod()或@classmethod修饰器定义,把类作为第一个参数传递  

  区别:类方法咦类本身作为第一个参数(习惯用cls接收,静态方法没有参数)

class Animal:
    def __init__(self,name,color):
        self.name = name
        self.color = color

    @classmethod   # 相当于    run = classmethod(run)
    def run(cls):    # 能被转化为类方法的方法,第一个参数必须接收一个对象,该对象(cls)代表类本身
        print("动物在跑...")

    def drink(cls,a,b,c):
        print("动物在喝水...")

    animal_drink = classmethod(drink)   # 通过classmethod()方法将drink方法转换为类方法

animal = Animal("小狗","棕色")
animal.run()

animal.animal_drink(1,2,3)
Animal.animal_drink(4,5,6)
classmethod
class Person(object):
    @staticmethod    # 相当于    play = staticmethod(play)
    def play():
        print("人在玩耍...")
    def work():
        print("working...")
    person_work = staticmethod(work)  # 使用staticmethod()函数将work()方法转换为静态方法
per = Person()
per.play()   # 使用实例化对象调用“静态方法”
Person.play()  # 使用类调用“静态方法”
print("*************************************************************")
per.person_work()
Person.person_work()
staticmethod

 

四、继承

  继承是为代码复用 和设计复用而设计的,是面向对象程序设计的重要特性之一。设计一个新类时,如果可以及继承一个已有的设计良好的类然后进行二次开发,无疑会大幅度减少开发工作量。

  在继承关系中,已有的、设计好的类称为父类或基类,新设计的类称为子类或者派生类。派生类可以继承父类的共有成员,但是不能继承其私有成员。如果需要在派生类中调用基类的方法,可以使用内置函数super()或者通过“基类名.方法名()”的方式来实现这一目的。

class Person:
    def __init__(self,name,age,sex):
        self.__name = name
        self.__age = age
        self.__sex = sex
    def play(self):
        print("人在玩耍...")
    def setName(self,name):
        self.__name = name
    def getName(self):
        return self.__name
    def setAge(self,age):
        if age<=0 or age >= 120:
            print("年龄不合法!")
        else:
            self.__age = age
    def getAge(self):
        return self.__age
class Worker(Person):
    def __init__(self,name,age,sex,skill):
        Person.__init__(self,name,age,sex)
        self.skill = skill
    def play(self):    # Worker类中重写了父类的play()方法
        print("工人在娱乐...")
     #   Person.play(self)

w = Worker("汤姆",25,"","修车")
w.play()
w.setAge(35)
print("年龄是:",w.getAge())
继承

 

 多重继承

  python支持多重继承,即一个类可以继承多个父类。注意:子类根据父类的顺序继承构造方法。

class Fruit:
    def __init__(self,name,price):
        print("fruit init...")
        self.name = name
        self.price = price
    def grow(self):
        print("水果生长...")

class Vegetable:
    def __init__(self):
        print("vegetable init...")
    def plant(self):
        print("种植蔬菜...")

class Watermelon(Vegetable,Fruit):
    pass

w = Watermelon()
w.grow()
w.plant()
多继承

五、抽象类

  抽象类是对一类事物特征行为的抽象,可以包含抽象方法

  在python3中可以使用abc模块,该模块中一个元素ABCMeta和修饰器@abstractmethod。

  1.抽象类不能被直接实例化 

  2.抽象类中的抽象方法在子类中必须重写,否则无法实例化该抽象类的子类对象

class Animal(metaclass=ABCMeta):
    def __init__(self,name,color):
        self.name = name
        self.color = color
    @abstractmethod
    def eat(self):
        pass
    def sleep(self):
        print("动物睡觉...")
class Dog(Animal):
    def eat(self):  # 重写继承而来的抽象方法
        print("小狗啃骨头...")
dog = Dog("旺财","黄色")
dog.eat()
dog.sleep()
abstractmethod

六、@property装饰器的应用

  @property使方法像属性一样调用,就像是一种特殊的属性

  @property装饰器使属性的访问更加方便,而且可以对属性的赋值加入检查机制

class Person:
    def __init__(self,name,age):
        self.__name = name
        self.__age = age

    @property   # @property 将age()方法转变为age属性
    def age(self):
        return self.__age

    @age.setter
    def age(self,age):
        if age <= 0 or age >= 120:
            raise ValueError("年龄不符合要求,必须是0~120之间")  # 引发异常
        self.__age = age

    def __str__(self):
        return "我叫" + self.__name + ",今年" + str(self.__age) + "岁了"


per = Person("令狐冲",20)
per.age = 50   # 设置age属性,会自动触发由@age.setter修饰的方法
print(per.age) # 访问age属性,该age属性是由@property装饰的方法得来的,属性名就是@property修饰的方法名,属性值是装饰的方法返回值
print(per)
property

七、多态

  多态:多态值得是一类事物有多钟形态

  鸭子类型是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由“当前方法和属性的集合”决定。“当看到一只鸟走起来想鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

  结论:Python 崇尚鸭子类型,即“如果看起来像、叫声而且走起路来像鸭子,那么它就是鸭子”

八、运算符重载

  Python把运算符和类的内置方法关联起来,每个运算符都对应1个函数

  __add__(self,other)表示加法运算符"+"

  __sub__(self,other)表示减法运算符“-”

  __gt__(self,other)表示减法运算符“>”

  __lt__(self,other)表示减法运算符“=”

  __eq__(self,other)表示减法运算符“==”

class Student:
    def __init__(self,name,age,sex,score):
        self.name = name
        self.age = age
        self.sex = sex
        self.score = score
    def __add__(self, other):
        return self.score + other.score
    def __sub__(self, other):
        return self.score - other.score
    # 小于
    def __lt__(self, other):
        return self.score < other.score
    # 大于
    def __gt__(self, other):
        return self.score > other.score
    # 等于
    def __eq__(self, other):
        return self.age == other.age
    # 大于等于
    def __ge__(self, other):
        return self.score >= other.score
stu1 = Student("张三",25,"",85)
stu2 = Student("李四",25,"",70)
print(stu1 + stu2)  # stu1 + stu2相当于:  stu1.__add__(stu2)
print(stu1 == stu2) # 默认比较的是内存地址是否相同,但可以通过在类中实现__eq__(self,other)改变默认的比较规则
print(stu1 - stu2)
print(stu1 > stu2)
print(stu1 < stu2)
print(stu1 >= stu2)
View Code

 

 

 

  

 

posted @ 2018-08-25 17:47  空谷幽兰wusj  阅读(195)  评论(0)    收藏  举报