1. 程式人生 > >面向物件三大特點

面向物件三大特點

封裝:
1.封裝是面向物件程式設計的一大特點
2.面向物件程式設計的第一步,將屬性和方法封裝到一個抽象的類中(抽象是因為類不能被直接使用)
3.外界使用類建立物件,然後讓那個物件呼叫方法
4.物件方法的細節都被封在類的內部
需求
1.小明體重75.0公斤
2.每次跑步會減肥0.5公斤
3每次吃東西體重會增加1公斤
4.小美的體重是45.0公斤
class Person:
    def  __init__(self,name,weight):
        #初始化方法中增加兩個引數由外界傳值
        #self.屬性=形參
        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.weight +=1
xm = Person('小明',75.0)
xm.run()
xm.eat()
print xm

 

案例2:擺放傢俱
需求:
1.房子有戶型,總面積和傢俱名稱列表
   新房子沒有任何的傢俱
2.傢俱有名字和佔地面積,其中
   床:佔4平米
   衣櫃:佔2平面
   餐桌:佔1.5平米
3.將以上三件傢俱新增到房子中
4.列印房子時,要求輸出:戶型,總面積,剩餘面積,傢俱名稱列表
被使用的類應該先開發
class Furniture:
    def __init__(self,name,area):
        self.name = name
        self.area = area
    def __str__(self,*args):
        return '[%s] 佔地 %.2f'%(self.name,self.area)
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'\
            %(self.house_type,self.area,self.free_area,self.item_list)
    def add_item(self,item):
        if self.free_area < item.area:
            print '%s 的面積太大了,無法新增' %item.name
            return
        self.item_list.append(item.name)
        self.free_area -= item.area

bed = Furniture('bed',4)
chest = Furniture('chest',2)
table = Furniture('table',1.5)
# print bed
# print chest
# print table
my_house = House('兩室一廳',60)
my_house.add_item(bed)
my_house.add_item(chest)
my_house.add_item(table)
print my_house

需求:
1.士兵瑞恩有一把AK47
2.士兵可以開火(士兵開火扣動的是扳機)
3.槍 能夠 發射子彈(把子彈發射出去)
4.槍 能夠 裝填子彈 --增加子彈的數量
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):
        if self.bullet_count <= 0:
            print '[%s]沒有子彈了。。。' %self.model
            return
        else:
            self.bullet_count -= 1
        print '[%s]tututu ,,,[%d]' %(self.model,self.bullet_count)

class Soldier:
    def __init__(self,name):
        self.name = name
    def fire(self):
        if self.gun == None:
            print '沒有槍'
            return
        print 'go'
        self.gun.add_bullet(50)
        self.gun.shoot()
ak47=Gun('AK47')
ryan = Soldier('Ryan')
ryan.gun = ak47
ryan.fire()
print ryan.gun

私有屬性和私有方法
應用場景及定義方式
應用場景
   在實際開發中,物件的某些屬性或方法可能只希望在物件的內部使用,而不希望在外部被訪問到
   私有屬性 就是 物件 不希望公開的 屬性
   私有方法 就是 方法 不希望公開的 方法
定義方法
   在定義屬性或方法時,在屬性名或者方法名前增加兩個下劃線,定義的就是私有屬性或方法
class Women:
    def __init__(self,name):
        self.name = name
        self.__age = 18
    def __secret(self):
        print '%s 的年齡是 %d' %(self.name,self.__age)

lily = Women('lily')
print lily.name
# 私有屬性,外界不能直接訪問
#print lily.age
# 私有方法,外界不能直接呼叫
lily.secret()

面向物件的特徵
    1.封裝:根據職責將屬性和方法封裝到一個抽象的類中
    2.繼承:實現程式碼的重用,相同程式碼不需要重複的寫
    3.多型
單繼承
繼承:子類擁有父類的所有屬性和方法
class 類名(父類):
    def  子類特有方法
子類也叫派生類
父類也叫基類
class Animal(object):
    def eat(self):
        print '吃'
    def drink(self):
        print '喝'
    def  run(self):
        print '跑'
    def  sleep(self):
        print '睡'


class Cat(Animal):
    #子類擁有父類的所有屬性和方法
    def call(self):
        print '喵喵'
class Dog(Animal):
    def bark(self):
        print '汪汪'
class Hellokitty(Cat):
    def speak(self):
        print  '我可以說日語'
#建立一個貓物件,繼承Animal的所有屬性和方法
mao = Cat()
mao.call()
#建立一個狗物件,繼承Animal的所有屬性和方法
gou = Dog()
gou.run()
gou.bark()
#建立一個hellokitty物件,繼承Cat的所有屬性和方法
"""
繼承的傳遞性:(爺爺 父親 兒子)
1.c類從b類繼承,b類又從a類繼承
2.那麼c類就具有b類和a類的所有屬性和方法
子類擁有父親以及父類的父類中的封裝的所有屬性和方法
"""
kt=Hellokitty()
kt.speak()
kt.run()
kt.call()
#子類繼承自父類,可以直接享受父類中已經封裝好的方法
#子類中應該根據自己的職責,封裝子類特有的屬性和方法

重寫父類方法:
    1.覆蓋父類的方法
    2.擴充套件父類的方法
class Animal:
    def eat(self):
        print '吃'
    def drink(self):
        print '喝'
    def  run(self):
        print '跑'
class  Cat(Animal):
    #子類擁有父類的所有方法和屬性
    def call(self):
        print '喵喵'
class Hellokitty(Cat):
    def speak(self):
        print '我可以說日語'
    def call(self):
        #針對子類特有的需求,編寫程式碼
        print '你好'
        #呼叫原本在父類中封裝的程式碼
        Cat.call(self)
        #增加其他的子類的程式碼
        print '####'
kt = Hellokitty()
#如果子類中,重寫了父類的方法
#在執行中,只會呼叫子類中重寫的父類的方法而不會呼叫父類的方法
kt.call()

注意init方法也可以被覆蓋所以要就加上

Bird.__init__(self)
class Bird:
    def __init__(self):
        self.hungry = True
    def eat(self):
        if self.hungry:
            print '吃....'
            self.hungry = False
        else:
            print  'No thants'
class SongBird(Bird):
    def __init__(self):
        Bird.__init__(self)
        self.sound = 'Squawk!'
    def sing(self):
        print self.sound
littlebird = SongBird()
littlebird.eat()
littlebird.sing()

多繼承的順序

class C(A,B)  繼承A(如果A,B的方法名稱一樣)

class C(B,A)繼承B(如果A,B的方法名稱一樣)

類的私有屬性和私有方法
    1.子類物件不能在自動的方法內部,直接訪問物件的私有屬性和私有方法
    2.子類物件可以通過父類的公有方法直接訪問到私有屬性和私有u方法
私有屬性,私有方法,私有方法是物件的隱私,不對外公開,外界以及子類都不能直接訪問
私有屬性,私有方法常用做一些內部的事情
class A:
    def __init__(self):
        self.num1 = 100
        self.__num2 = 200
    def __test(self):
        print '私有方法 %d %d' % (self.num1, self.__num2)
    def test(self):
        print '父類的共有方法 %d' % self.__num2
        self.__test()
class B(A):
    def demo(self):
        # 在子類的物件方法中,不能訪問父類的私有屬性
        # # print '訪問父類的私有屬性 %d '%self.__num2
        # 在子類物件的方法中,不能呼叫父類的私有方法
        # # self.__test()
        self.test()

b = B()
b.demo()

# 在外界不能直接訪問物件的私有屬性/呼叫私有方法
print b.__num2
b.__test()