24-1 面向对象(创建类和对象、面向对象三大特性)

 

编程其实就是一个将具体世界进行抽象化的过程,面向对象编程(Object Oriented Programming,OOP)是利用“类”和“对象”来创建各种模型来实现对真实世界的描述。

  • 类(class):      一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的具备的共同的属性、共同的方法。
  • 对象(object): 一个对象即是一个类的实例化来的,一个类可以实例化出多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之间有共性,亦有不同。

python既支持函数式编程也支持面向对象编程(而比如Java和C#来说只支持面向对象编程),一般在Python开发中,全部使用面向对象或面向对象和函数式混合使用。

 

创建类和对象

创建对象的过程,就是将类实例化的过程。

 1. 创建类和对象

# 创建类
class Student(object):                   # object写不写都行,因为系统内部都会给写上。所有类都继承object   
    
    school = "oldboy"                    # 静态字段
    term = "fulltack2"   
    
    def __init__(self, name, age):       # 创建对象时,自动执行的特殊方法。
        self.name = name
        self.age = age

    def show(self):                      # 类中定义的函数叫方法。
        print(self.name, self.age )

    def func(self):
        return self.age + 2


# 创建对象
obj1 = Student("alex", 18)               # 创建对象,类名称后加括号
obj2 = Student("jack", 20)

# 调用
obj1.show()                              # 调用方式一:通过类对象指针找到方法,self参数自动传入。建议这样用
Student.show(obj1)                       # 调用方式二:通过类找到其中的方法,参数需要自己传入

ret = obj1.func()                        # 接收方法的返回值
print(ret)                               # 输出:20

 2. 实例化的内部过程

“实例化”, 就是把一个虚拟的抽象的类,通过这个动作,变成了一个具体的对象了, 这个对象就叫做实例。

(1)__init__()

类中的__init__方法叫初始化方法(或构造方法)。在生成一个角色时要初始化的一些属性就填写在这里。

当解释器解释到obj = 类名() 这句话时,会做两件事情:①创建对象 ②通过对象执行类中的构造方法__init__() 

(2)self

self 是一个形参,它代指对象本身。如:执行 obj1 = Student('alex', 18 ) 时,self 等于 obj1; 当执行 obj2 = Student('jack', 20) 时,self 等于 obj2。

第一个参数名称必须为self是类的方法(普通方法)与普通的函数的一个区别,但是在调用这个方法的时候不用给这个参数赋值,因为Python会提供这个值。

按照惯例它的名称是self,虽然你可以给这个参数任何名称,但是 强烈建议 你使用self这个名称。

为什么要有self参数?

假设有一个类称为MyClass和这个类的一个实例MyObject。

当调用这个对象的方法MyObject.method(arg1, arg2)时,Python处理时实际会转为MyClass.method(MyObject, arg1, arg2),self 即代指MyObject。

调用类中的一个方法时,你得告诉人家你是谁,否则如何操作对象中的属性?!

 

 

面向对象三大特性

面向对象的三大特性是指:封装、继承和多态。

一、 封装(Encapsulation

其实就是使用构造方法将内容装到某个具体对象中,然后通过对象直接或者self间接获取被封装的内容:

  • 通过对象直接调用        对象名.属性名
  • 通过self间接调用         self.属性名

 

二、继承

1. 继承

继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

通过继承创建的新类称为“子类”或“派生类”。

被继承的类称为“基类”、“父类”或“超类”。

OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段

class 父类:
    pass

class 子类(父类):
    pass
class Animal:
    def eat(self):
        print("%s 吃 " % self.name)

    def drink(self):
        print("%s 喝 " % self.name)

    def shit(self):
        print("%s 拉 " % self.name)

    def pee(self):
        print("%s 撒 " % self.name)


class Cat(Animal):
    def __init__(self, name):
        self.name = name
        self.breed = ''

    def cry(self):
        print('喵喵叫')


class Dog(Animal):
    def __init__(self, name):
        self.name = name
        self.breed = ''

    def cry(self):
        print('汪汪叫')





c1 = Cat('小明家的小黑猫')
c1.eat()                           # 小明家的小黑猫 吃

d1 = Dog('胖子家的小瘦狗')
d1.eat()                           # 胖子家的小瘦狗 吃
狗猫实例
#!_*_coding:utf-8_*_
# __author__:"Alex Li"


class SchoolMember(object):
    members = 0  # 初始学校人数为0

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

    def tell(self):
        pass

    def enroll(self):
        '''注册'''
        SchoolMember.members += 1
        print("\033[32;1mnew member [%s] is enrolled,now there are [%s] members.\033[0m " % (
        self.name, SchoolMember.members))

    def __del__(self):
        '''析构方法'''
        print("\033[31;1mmember [%s] is dead!\033[0m" % self.name)


class Teacher(SchoolMember):
    def __init__(self, name, age, course, salary):
        super(Teacher, self).__init__(name, age)
        self.course = course
        self.salary = salary
        self.enroll()

    def teaching(self):
        '''讲课方法'''
        print("Teacher [%s] is teaching [%s] for class [%s]" % (self.name, self.course, 's12'))

    def tell(self):
        '''自我介绍方法'''
        msg = '''Hi, my name is [%s], works for [%s] as a [%s] teacher !''' % (self.name, 'Oldboy', self.course)
        print(msg)


class Student(SchoolMember):
    def __init__(self, name, age, grade, sid):
        super(Student, self).__init__(name, age)
        self.grade = grade
        self.sid = sid
        self.enroll()

    def tell(self):
        '''自我介绍方法'''
        msg = '''Hi, my name is [%s], I'm studying [%s] in [%s]!''' % (self.name, self.grade, 'Oldboy')
        print(msg)


if __name__ == '__main__':
    t1 = Teacher("Alex", 22, 'Python', 20000)
    t2 = Teacher("TengLan", 29, 'Linux', 3000)

    s1 = Student("Qinghua", 24, "Python S12", 1483)
    s2 = Student("SanJiang", 26, "Python S12", 1484)

    t1.teaching()
    t2.teaching()
    t1.tell()
教学实例

2. 重写 

 如果父类中的某个方法不想继承,就在子类中写一个同名的方法。解释器找到子类中该名称的方法后,就不再去找父类中的同名方法。查找顺序如下:

class F:
    def f1(self):
        print('F.f1')

    def f2(self):
        print('F.f2')


class S(F):
    def s1(self):
        print('S.s1')
    def f2(self):           # 同名,父类中f2不再继承
        print('S.f2')



obj = S()
obj.f1()                    # F.f1
obj.f2()                    # S.f2
示例

3. 子类中手动执行父类中的方法

super(子类, self).父类中的方法(...)
父类名.父类中的方法(self,...)

class F:
    def f1(self):
        print('F.f1')

    def f2(self):
        print('F.f2')


class S(F):
    def s1(self):
        print('S.s1')
    def f2(self):
        print('S.f2')
        super(S, self).f2()     # 找到父类,执行父类中f2  方式一,推荐用这种方法
        F.f2(self)              # 找到父类,执行父类中f2  方式二



obj = S()
obj.f1()                    # F.f1
obj.f2()                    # S.f2
                            # F.f2
                            # F.f2
示例

4. 多继承

a. 左侧优先

一个子类同时继承多个类时,先搜索左边的类。

class F1:
    def a(self):
        print('F1.a')

class F2:
    def a(self):
        print('F2.a')
    def b(self):
        print('F2.b')


class S(F1, F2):
    pass

obj =S()
obj.a()                # F1.a
obj.b()                # F2.b
View Code

b. 一条道走到头,再回头

class F0:
    def a(self):
        print('F0.a')


class F1(F0):
    def b(self):
        print('F1.b')


class F2:
    def a(self):
        print('F2.a')
    def c(self):
        print('F2.c')


class S(F1,F2):
    pass


obj =S()
obj.a()                       # F0.a
obj.c()                       # F2.c
示例

c. 同一个根时,根最后执行

 

# 以次改变函数名,一步步试
class Base:
    def a(self):
        print('Base.a')


class F0(Base):
    def a(self):
        print('F0.a')


class F1(F0):
    def a(self):
        print('F1.a')


class F3(Base):
    def a(self):
        print('F3.a')

class F2(F3):
    def a(self):
        print('F2.a')


class S(F1,F2):
    pass


obj =S()
obj.a()
示例

 

 三、多态

多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。
 
Pyhon 很多语法都是支持多态的,比如 len(),sorted(), 你给len传字符串就返回字符串的长度,传列表就返回列表长度。

 Python多态示例:

class Animal(object):
    def __init__(self, name):  # Constructor of the class
        self.name = name

    def talk(self):  # Abstract method, defined by convention only
        raise NotImplementedError("Subclass must implement abstract method")


class Cat(Animal):
    def talk(self):
        print('%s: 喵喵喵!' % self.name)


class Dog(Animal):
    def talk(self):
        print('%s: 汪!汪!汪!' % self.name)


def func(obj):  # 一个接口,多种形态
    obj.talk()


c1 = Cat('小晴')
d1 = Dog('李磊')

func(c1)
func(d1)

 

参考:

http://www.cnblogs.com/wupeiqi/p/4493506.html

http://www.cnblogs.com/alex3714/articles/5188179.html

http://python.jobbole.com/81921/

posted @ 2017-07-01 17:28  seaidler  阅读(131)  评论(0)    收藏  举报