Python的OOP面向对象

# 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教程。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容