Python面向对象-封装 继承 多态

1.使用类名创建对象的时候,创建对象,Python解释器

会自动为对象在内存中分配空间。调用初始化方法为对象的属性设置初始值

这个初始化方法是init方法

使用类名创建对象的时候哦,会自动调用初始化方法

2.继承的语法
class 类名(父类)
def 子类特意有的方法

重写父类方法有两种情况
1.覆盖父类方法 2.对父类方法进行扩展

1.覆盖父类的方法
如果在开发中,父类父类方法的实现和子类方法的实现
完全不同,就可以使用覆盖的方式
在子类中重新编写父类的方法

具体实现方式,就相当于在子类中定义了
一个和父类同名的方法并实现
重写之后 在运行时 只会调用子类的重写方法
而不会再调用父类封装的方法

对父类的方法进行扩展
如果在开发中,子类的方法实现包含父类的方法实现
(父类原本封装的方法实现是子类方法的一部分就可以
使用扩展方法)
1.在子类中重写父类的方法
2.在需要的位置使用 父类名。方法(self)来调用父类方法
的执行(使用父类名称调用父类方法)
3.代码其他的位置针对子类的需求,编写子类特有的代码实现

“””
继承的传递性:(爷爷 父亲 儿子)
1.C类从B类继承,B类又从A类继承
2.那末C类就具有B类和A类的所有属性和方法
子类具有父类及父类的父类中封装的所有属性和方法

“””
继承自己示例

class Person():
    def __init__(self,name,weight):
        self.name = name
        self.weight = weight
    def __str__(self):
        return '我的名字叫 %s 体重是%.2f' % (self.name ,self.weight)
    def run(self):
        print '%s 爱跑步' % self.name
        self.weight -=0.5
    def eat(self):
        print '%s 吃东西' % self.name
        self.eat +=1.0

xiaoming = Person('xiaoming',50.0)
xiaoming.run()
print xiaoming

小狗爱睡觉 小狗爱乱跳示例

class dog():
    def sleep(self):
        print '小狗爱睡觉'
    def jump(self):
        print '小狗爱乱跳'

jia = dog()
jia.sleep()
jia.jump()
print jia
addr = id(jia)
#%x:打印格式为十六进制
print '%x' % addr
#%d:打印格式为十进制
print '%d' % addr

#再创建一个狗类对象
lazy_dog = dog()
lazy_dog.sleep()
lazy_dog.jump()
print lazy_dog

fool_dog = lazy_dog
print fool_dog

示例三

class Cat():
    def __init__(self,new_name):
        self.name = new_name
        print '%s 来了' % self.name
    def __del__(self):
        print '%s 走了' % self.name

tom = Cat('tom')
print tom.name

del tom
print '-' * 50

继承的传递性:(爷爷 父亲 儿子)
1.C类从B类继承,B类又从A类继承
2.那末C类就具有B类和A类的所有属性和方法
子类具有父类及父类的父类中封装的所有属性和方法

"""
class Animal():
    def eat(self):
        print '吃'
    def drink(self):
        print '喝'
    def run(self):
        print '跑'
    def sleep(self):
        print '睡'

class Cat(Animal):
    def call(self):
        print '啊啊啊'
class redcat(Cat):
    def speak(self):
        print 'yiyiyi'


Tom = Animal()
Tom.eat()
Tom.drink()
Tom.run()
Tom.sleep()

单继承
1.继承的概念,语法和特点
继承的概念:子类拥有父类的所有方法和属性(子类只需要封装自己特有的)
2.继承的语法
class 类名(父类)
def 子类特意有的方法

重写父类方法有两种情况
1.覆盖父类方法 2.对父类方法进行扩展

1.覆盖父类的方法
如果在开发中,父类父类方法的实现和子类方法的实现
完全不同,就可以使用覆盖的方式
在子类中重新编写父类的方法

具体实现方式,就相当于在子类中定义了
一个和父类同名的方法并实现
重写之后 在运行时 只会调用子类的重写方法
而不会再调用父类封装的方法

对父类的方法进行扩展
如果在开发中,子类的方法实现包含父类的方法实现
(父类原本封装的方法实现是子类方法的一部分就可以
使用扩展方法)
1.在子类中重写父类的方法
2.在需要的位置使用 父类名。方法(self)来调用父类方法
的执行(使用父类名称调用父类方法)
3.代码其他的位置针对子类的需求,编写子类特有的代码实现

示例一

class Bird():
    def __init__(self):
        self.hungry = True
    def eat(self):
        if self.hungry:
            print 'Aaaaaaa'
            self.hungry =False
        else:
            print 'No Thinks!'

class SingBird(Bird):
    def __init__(self):
        self.sound = 'Squawk'
        Bird.__init__(self)
    def sing(self):
        print self.sound


#bird = Bird
#bird.eat()

littlebird = SingBird()
littlebird.eat()
littlebird.sing()

示例二

"""
class A():
    #def test(self):
        print '----------'
    def demo(self):
        print '+++++++++++'
class B():
    def test(self):
        print '**********'
    #def demo(self):
        print '==========='
class C(B,A):
    pass


c = C()
c.test()
c.demo()

新式类 旧式类(经典类)

In [1]: class A(): #旧式类 继承的功能少
   ...:     pass
   ...: 

In [2]: a = A()

In [3]: dir(a)
Out[3]: ['__doc__', '__module__']

In [4]: class B(object): #新式类  继承功能多
   ...:     pass
   ...: 

In [5]: b = B()

In [6]: dir(b)
Out[6]: 
['__class__',
 '__delattr__',
 '__dict__',
 '__doc__',
 '__format__',
 '__getattribute__',
 '__hash__',
 '__init__',
 '__module__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__']

封装房子示例

class HouseItem():
    def __init__(self,name,area):
        self.name = name
        self.area = area
    def __str__(self):
        return '%s 占地 %.2f' %(self.name,self.area)

bed = HouseItem('bed' ,4)
print bed
chest = HouseItem('chest' ,5)
print chest
tables = HouseItem('tables' ,1.5)
print tables

class House():
    def __init__(self,house_type,area):
        self.house_type = house_type
        self.area = area
        self.free_area = area
        self.item_list = []
    def __str__(self):
        return '户型:%s\n总面积:%.2f [剩余面积:%.2f]\n家具列表:%s\n' \
              %(self.house_type,self.area,self.free_area,self.item_list)
    def add_item(self, item):
        print '要添加 %s' % item
        if item.area > self.free_area:
            print '%s 的面积太大,无法添加' % item.name
        self.item_list.append(item.name)
        self.free_area -= item.area


my_house = House('两室一厅',100)
my_house.add_item(bed)
my_house.add_item(chest)

封装士兵开枪示例

class Gun():
    def __init__(self,model):
        #枪的型号
        self.model = model
        #子弹数量
        self.bullet_count = 0
    def add_bullet(self,count):
        self.bullet_count += count
    def shoot(self):
        #1.判断子弹的数量
        if self.bullet_count <= 0:
            print '%s 没有子弹了' %self.model
            return
        #2.发射子弹
        print '%s 突突突 %d' % (self.model,self.bullet_count)
class Soldier():   #定义!
    def __init__(self,name):
        self.name = name
        self.gun = None
    def fire(self):
        #判断士兵有没有枪
        if self.gun == None:
            print '%s 还没有枪哈哈哈' %self.name
            return
        #高喊口号
        print 'go go go %s' %self.name
        #让枪装子弹
        self.gun.add_bullet(50)
        #让枪发射子弹
        self.gun.shoot()

#1.创建枪对象
ak47 = Gun('AK47')
ak47.add_bullet(50)
ak47.shoot()

#2.创建士兵
ryan = Soldier('Ryan')
ryan.gun = ak47
ryan.fire()
print ryan.gun

多态:不同的子类(继承知识)对象调用相同的方法,产生不同的结果

class Jia(object):
    def __init__(self,name):
        self.name = name
    def say(self):
        print '%s amazing'% self.name

class Mr(Jia):
    def say(self):
        print '%s happily'% self.name


hh = Jia('hh')

多态

类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Person 派生出 Student和Teacher ,并都写了一个 whoAmI() 方法:

class Person(object):
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
    def whoAmI(self):
        return 'I am a Person, my name is %s' % self.name

class Student(Person):
    def __init__(self, name, gender, score):
        super(Student, self).__init__(name, gender)
        self.score = score
    def whoAmI(self):
        return 'I am a Student, my name is %s' % self.name

class Teacher(Person):
    def __init__(self, name, gender, course):
        super(Teacher, self).__init__(name, gender)
        self.course = course
    def whoAmI(self):
        return 'I am a Teacher, my name is %s' % self.name

在一个函数中,如果我们接收一个变量 x,则无论该 x 是 Person、Student还是 Teacher,都可以正确打印出结果:

def who_am_i(x):
    print x.whoAmI()

p = Person('Tim', 'Male')
s = Student('Bob', 'Male', 88)
t = Teacher('Alice', 'Female', 'English')

who_am_i(p)
who_am_i(s)
who_am_i(t)
#运行结果:

#I am a Person, my name is Tim
#I am a Student, my name is Bob
#I am a Teacher, my name is Alice

这种行为称为多态。也就是说,方法调用将作用在 x 的实际类型上。s 是Student类型,它实际上拥有自己的 whoAmI()方法以及从 Person继承的 whoAmI方法,但调用 s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。

由于Python是动态语言,所以,传递给函数 who_am_i(x)的参数 x 不一定是 Person 或 Person 的子类型。任何数据类型的实例都可以,只要它有一个whoAmI()的方法即可:

class Book(object):
    def whoAmI(self):
        return 'I am a book'

这是动态语言和静态语言(例如Java)最大的差别之一。动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用。

任务

Python提供了open()函数来打开一个磁盘文件,并返回 File 对象。File对象有一个read()方法可以读取文件内容:

例如,从文件读取内容并解析为JSON结果:

import json
print json.load(f)

由于Python的动态特性,json.load()并不一定要从一个File对象读取内容。任何对象,只要有read()方法,就称为File-like Object,都可以传给json.load()。

请尝试编写一个File-like Object,把一个字符串 r’[“Tim”, “Bob”, “Alice”]’包装成 File-like Object 并由 json.load() 解析。

?不会了怎么办

只要为Students类加上 read()方法,就变成了一个File-like Object。

参考代码:

import json

class Students(object):
    def read(self):
        return r'["Tim", "Bob", "Alice"]'

s = Students()

print json.load(s)

你可能感兴趣的:(Linux自动化运维)