美文网首页
Python的OOP面向对象

Python的OOP面向对象

作者: 逝水流华年 | 来源:发表于2017-05-11 09:20 被阅读0次
    # OOP 实战通过简单的case 更好的理解OOP思想, 如果使用代码,可以下载附件修改为.py即可
    
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    '''
    Created on 2017年3月24日
    
    @author: fWX457893
    '''
    # 类的封装  
    class Student(object):
        # __ 双下划线可使变量私有变成private,只有在函数每部可以访问,外部不能访问,    
        def __init__(self, name, score, **kw):
            self.__name = name
            self.__score = score
            self.kw = kw
        
        # 如果还想要让外部访问,可是添加方法  get_name, get_score, get_kw
        def get_name(self):
            return self.__name
        def get_score(self):
            return self.__score
        # 又要允许外部代码修改score怎么办?可以再给Student类增加set_score方法:
        def set_name(self, name):
            self.__name = name
        def set_score(self, score):
            if 0 <= score <= 100:
                self.__score = score
            else :
                raise ValueError('bad score')
        
        def print_score(self):
            print('%s: %s \t %s' % (self.__name, self.__score, self.kw))
            
        def get_grade(self):
            if self.__score >= 90:
                return 'A'
            elif self.__score >= 60:
                return 'B'
            else :
                return"C"
    
    bart = Student('fyh', 100, address='bj')
    
    bart.print_score()
    
    bart.set_score(10)
    bart.print_score()
    
    grade = bart.get_grade()
    print grade
    # 表面上看,外部代码“成功”地设置了__name变量,但实际上这个__name变量和class内部的__name变量不是一个变量!
    # 内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量。不信试试:
    bart.__name = 'new name'
    print bart.__name
    bart.print_score()
    
    # -------------------------------------------------------------------------------
    # OOP 的 继承和多态
    class Animal(object):
        def run(self):
            print 'Animal is running...'
        def eat(self):
            print('Eating food...')
    
    class Dog(Animal):
        def run(self):
            print('Dog is running...')
    
        def eat(self):
            print('Dog eating meat...')
    
    
    class Cat(Animal):
        def run(self):
            print('Cat is running...')
    
        def eat(self):
            print('Cat eating fish...')
    
    
    ani = Animal()
    ani.run()
    
    cat = Cat()
    cat.run()
    
    def run_eat(animal):
        animal.run()
        animal.eat()
    
    run_eat(Animal())
    run_eat(Dog())
    run_eat(Cat())
    
    '''
    对于一个变量,我们只需要知道它是Animal类型,无需确切地知道它的子类型,就可以放心地调用run()方法,
    而具体调用的run()方法是作用在Animal、Dog、Cat还是Tortoise对象上,由运行时该对象的确切类型决定,
    这就是多态真正的威力:调用方只管调用,不管细节,而当我们新增一种Animal的子类时,
    只要确保run()方法编写正确,不用管原来的代码是如何调用的。这就是著名的“开闭”原则:
    
    对扩展开放:允许新增Animal子类;
    对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。
    
    继承还可以一级一级地继承下来,就好比从爷爷到爸爸、再到儿子这样的关系。而任何类,最终都可以追溯到根类object,这些继承关系看上去就像一颗倒着的树。
    
    '''
    
    # 
    '''
    静态语言 vs 动态语言
    
    对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。
    对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了:
    
    class Timer(object):
        def run(self):
            print('Start...')
    这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
    
    Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个read()方法,返回其内容。但是,许多对象,只要有read()方法,都被视为“file-like object“。
    许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了read()方法的对象。
    '''
    
    class Husky(Dog):
        def run(self):
            print('Husky is running...')
    
        def eat(self):
            print('Husky eating meat...')
            
    # 使用isinstance()
    # 对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数。
    # object -> Animal -> Dog -> Husky
    animal = Animal()
    dog = Dog()
    husky = Husky()
    
    print isinstance(husky, Husky), isinstance(husky, Dog), isinstance(husky, Animal)
    # True True True  husky 是husky dog object 但是 dog 不是husky 是dog object
    
    
    #定义一个父类一个子类
    class Province(object):
        def __init__(self,proname):
            self.proname=proname
        def ps(self):
            print('I am in %s'%self.proname)
    
    class City(Province):
        def __init__(self,proname,cityname):
            self.cityname=cityname
            Province.__init__(self,proname)
        def ps1(self):
            print('I\'m in %s-%s' %(self.proname,self.cityname))
    
    #定义一个独立的类
    class Timer(object):
        def ps(self):
            print('我不属于Province类或其子类,但我有ps方法我同样可以被调用')
        def ps1(self):
            print('我不属于Province类或其子类,但我有ps1方法我同样可以被调用')
    
    #定义一个函数
    def func(x):
        x.ps()
        x.ps1()
    
    #调用部分
    func(City('北京','海淀'))
    func(Timer())
    
    # 部分参考廖神的python教程。
    

    相关文章

      网友评论

          本文标题:Python的OOP面向对象

          本文链接:https://www.haomeiwen.com/subject/oeontxtx.html