面向對象【第1篇-面向對象設計】

面向對象

什麼是對象

對象若是要思考的話應該是咱們對任何事物的一個抽象的說明,舉個例椅子咱們能夠說是一個對象,桌子也能夠是個對象。可是這些都是咱們看得見或者摸得着的東西!python

在軟件開發中對象的定義也沒多大區別也是形容或者描述"東西",正式的講:對象是一個數據以及相關行爲的集合。數據庫

(舉個例子咱們來描述下椅子這個對象:編程

數據:長40釐米,寬50釐米,高100釐米模塊化

方法:能夠坐下,能夠打人,能夠吃飯,能夠睡覺....函數

工具

 

什麼是面向對象

面向對象的簡單的意思就是指向,因此面向對象的簡單意思就是"功能上指向建模對象(某個功能指向對象好比寫入數據庫功能指向某個對象)"網站

 

面向對象中的術語

常常搞混的:面向對象分析面向對象設計面向對象分析設計面向對象編程這些術語都是TMD什麼意思?spa

面向對象分析(OOA  Object-Oriented Analysis):設計

着眼於一個問題、系統或者任務的過程,而且識別這些對象以及對象間的交互。分析咱們都要作什麼,把一個網站(分析的對象),變成一個需求rest

最後需求出來:

  • 訂單查看
  • 訂單取消
  • 產品訂購

面向對象設計(OOD Object-Oriented Design):

把需求轉換爲實踐規範的過程,好比命名這些對象(命名)、定義行爲(方法)、定義接口~

面向對象編程(OOP  Object-Orientd programming):

是把設計轉化成一個能夠工做的程序的過程(寫代碼的過程)

 

可是實際上,在這個快節奏的世界,大部分開發恰好是一個"迭代式開發模型"。在迭代式開發中,會先模塊化、設計和編程實現任務重的小部分,而後評估這個程序並經過擴展來改善每個特性,包括在一系列短的週期裏增長新的特性

 

面向對象編程特性

從新理解一下 封裝、繼承、和多態

封裝

學面相對象的時候咱們知道分裝就是把:數據、方法封裝到一個對象中。那封裝的做用是什麼?

用一句話歸納:隱藏細節提供公共接口(隔離複雜度)

舉個很是形象的例子,看電視的時候咱們經過遙控器調節:節目數字、電視音量、聲道等信息,遙控器就是電視這個對象提供的接口,操控方法(節目數字、音量大小、),電視機的屬性(品牌、大小、等信息)

這裏電視給咱們提供的統一接口你只要按遙控器就能夠了,根本不須要管它是怎麼實現信號傳輸、音量的大小、節目的調節的。

class Television(object):
    def __init__(self, master):
        self.master = master

    def add_show(self):
        print('%s操做當前節目ID加1' % self.master)

    def subtract_show(self):
        print('%s操做當前節目ID減1' % self.master)

    def add_volume(self):
        print('%s操做當前電視音量加1' % self.master)
    
    def subtract_volume(self):
        print('%s操做當前電視音量加1' % self.master)

咱們操做電視的時候,只需使用提供的這幾個接口,具體內部怎麼實現的咱們不須要關心

 

繼承

接下來看下繼承,能夠經過「繼承」(Inheritance)「組合」(Composition)來實現。

組合

組合的概念:

眼(Eye)、鼻(Nose)、口(Mouth)、耳(Ear)是頭(Head)的一部分,因此類Head應該由類Eye、Nose、Mouth、Ear組合而成不是派生(繼承)而成

舉例來講:

class Eye(object):
    def __init__(self, person):
        self.person = person

    def look(self, something):
        print('%s look %s' % (self.person, something))


class Head(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        # 經過組合的方式吧Eye類裏的方法組合起來
        self.eye = Eye(self.name)
        
    def look(self, something):
        self.eye.look(something)
    
    ........

 

繼承

 先看一個接口的定義:建立一個沒有實現任何放的類,這個類簡單的告訴咱們這個類該作什麼,可是絕對沒有提供任何建議告訴咱們如何去作,在面向對象的世界裏這樣的的類稱之爲接口

繼承的概念就想一個家庭圖譜,好比你父親從你爺爺那裏繼承了姓氏(羅)你從你父親那裏繼承了姓氏(羅),這種關係稱之爲繼承。

 

多重繼承

舉個例子說就是你繼承了你父親眼睛的顏色,又繼承了你母親頭髮的顏色,這種在一個類中繼承多個類的狀況稱之爲:多重繼承

可是隻要兩個類有不一樣的藉口,對於一個多重繼承是無害的,可是若是咱們從兩個重疊藉口繼承就會變得不好。好比你繼承了"汽車類"又繼承了"摩托車"類,它們都有一個move方法,當你調用move方法的時候,這個合成類到底該怎麼作呢!

一般這種設計是錯誤的,出現這種狀況看看是否能夠把多重繼承刪掉,採用相似關聯或者組合的設計

 

多態

咱們能夠說:

封裝的做用是簡化代碼複雜度

繼承的做用是增長代碼重用性

那多態的做用呢?

多態的做用是增長接口重用性

先看一個接口的定義:建立一個沒有實現任何放的類,這個類簡單的告訴咱們這個類該作什麼,可是絕對沒有提供任何建議告訴咱們如何去作,在面向對象的世界裏這樣的的類稱之爲接口。

# !/usr/bin/env python3.5
# -*- coding:utf-8 -*-
# __author__ == 'LuoTianShuai'

import abc


# 定義交通工具類
class Vehicle(object):
    # 基類定義接口使用abc強制約束子類必須重寫move這個類
    @abc.abstractmethod
    def move(self):
        pass

    # 給他的意義他能讓乘坐它的人去某個地方


class Car(Vehicle):
    def __init__(self, car_name):
        self.car_name = car_name

    def move(self):
        print('%s正在移動.....' % self.car_name)


class Subway(Vehicle):
    def __init__(self, line_name):
        self.line_name = line_name

    def move(self):
        print('%s正在移動.....' % self.line_name)

"""
父類定義接口,子類實現,而後統一調用,只要你實現了這個接口誰管你是怎麼實現的,可是都是統一調用接口
只要這個工具能動、能運輸人 咱們就稱他爲交通工具
"""

benz = Car('Benz')
line10 = Subway('Beijing Subway line 10')

benz.move()
line10.move()

可是Python自己就是一們多態的語言動態語言,在Python中你不多據說多態的概念,在Python中的多態性一般稱爲鴨子類型:當看到一隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就能夠被稱爲鴨子

在鴨子類型中,關注的不是對象的類型自己,而是它是如何使用的。例如,在不使用鴨子類型的語言中,咱們能夠編寫一個函數,它接受一個類型爲鴨的對象,並調用它的走和叫方法。在使用鴨子類型的語言中,這樣的一個函數能夠接受一個任意類型的對象,並調用它的走和叫方法。若是這些須要被調用的方法不存在,那麼將引起一個運行時錯誤。任何擁有這樣的正確的走和叫方法的對象均可被函數接受的這種行爲引出了以上表述,這種決定類型的方式所以得名。

# coding=utf-8
class Duck(object):
    def quack(self):
        print("鴨子在嚎叫")


class Swan(object):
    def quack(self):
        print("天鵝在嚎叫")


class Goose(object):
    def quack(self):
        print("鵝在嚎叫")


def in_the_forest(duck):
    duck.quack()


duck_obj = Duck()
bird_obj = Swan()
doge_obj = Goose()
for x in [duck_obj, bird_obj, doge_obj]:
    in_the_forest(x)
相關文章
相關標籤/搜索