1. 程式人生 > >5.7抽象類

5.7抽象類

Speak ctu 如果 === class int 基類 type operator

接口與歸一化設計

1.什麽是接口

hi boy,給我開個查詢接口。。。此時的接口指的是:自己提供給使用者來調用自己功能的方式\方法\入口,java中的interface使用如下

=================第一部分:Java 語言中的接口很好的展現了接口的含義: IAnimal.java
/*
* Java的Interface接口的特征:
* 1)是一組功能的集合,而不是一個功能
* 2)接口的功能用於交互,所有的功能都是public,即別的對象可操作
* 3)接口只定義函數,但不涉及函數實現
* 4)這些功能是相關的,都是動物相關的功能,但光合作用就不適宜放到IAnimal裏面了 */

package com.oo.demo;
public interface IAnimal {
    public void eat();
    public void run(); 
    public void sleep(); 
    public void speak();
}

=================第二部分:Pig.java:豬”的類設計,實現了IAnnimal接口 
package com.oo.demo;
public class Pig implements IAnimal{ //如下每個函數都需要詳細實現
    public void eat(){
        System.out.println("Pig like to eat grass");
    }

    public void run(){
        System.out.println("Pig run: front legs, back legs");
    }

    public void sleep(){
        System.out.println("Pig sleep 16 hours every day");
    }

    public void speak(){
        System.out.println("Pig can not speak"); }
}

=================第三部分:Person2.java
/*
*實現了IAnimal的“人”,有幾點說明一下: 
* 1)同樣都實現了IAnimal的接口,但“人”和“豬”的實現不一樣,為了避免太多代碼導致影響閱讀,這裏的代碼簡化成一行,但輸出的內容不一樣,實際項目中同一接口的同一功能點,不同的類實現完全不一樣
* 2)這裏同樣是“人”這個類,但和前面介紹類時給的類“Person”完全不一樣,這是因為同樣的邏輯概念,在不同的應用場景下,具備的屬性和功能是完全不一樣的 */

package com.oo.demo;
public class Person2 implements IAnimal { 
    public void eat(){
        System.out.println("Person like to eat meat");
    }

    public void run(){
        System.out.println("Person run: left leg, right leg");
    }

    public void sleep(){
        System.out.println("Person sleep 8 hours every dat"); 
    }

    public void speak(){
        System.out.println("Hellow world, I am a person");
    } 
}

=================第四部分:Tester03.java
package com.oo.demo;

public class Tester03 {
    public static void main(String[] args) {
        System.out.println("===This is a person==="); 
        IAnimal person = new Person2();
        person.eat();
        person.run();
        person.sleep();
        person.speak();

        System.out.println("\n===This is a pig===");
        IAnimal pig = new Pig();
        pig.eat();
        pig.run();
        pig.sleep();
        pig.speak();
    } 
}

 java中的interface

2. 為何要用接口

接口提取了一群類共同的函數,可以把接口當做一個函數的集合。

然後讓子類去實現接口中的函數。

這麽做的意義在於歸一化,什麽叫歸一化,就是只要是基於同一個接口實現的類,那麽所有的這些類產生的對象在使用時,從用法上來說都一樣。

歸一化的好處在於:

  1. 歸一化讓使用者無需關心對象的類是什麽,只需要的知道這些對象都具備某些功能就可以了,這極大地降低了使用者的使用難度。
  2. 歸一化使得高層的外部使用者可以不加區分的處理所有接口兼容的對象集合
    1. 就好象linux的泛文件概念一樣,所有東西都可以當文件處理,不必關心它是內存、磁盤、網絡還是屏幕(當然,對底層設計者,當然也可以區分出“字符設備”和“塊設備”,然後做出針對性的設計:細致到什麽程度,視需求而定)。
    2. 再比如:我們有一個汽車接口,裏面定義了汽車所有的功能,然後由本田汽車的類,奧迪汽車的類,大眾汽車的類,他們都實現了汽車接口,這樣就好辦了,大家只需要學會了怎麽開汽車,那麽無論是本田,還是奧迪,還是大眾我們都會開了,開的時候根本無需關心我開的是哪一類車,操作手法(函數調用)都一樣

3. 模仿interface

在python中根本就沒有一個叫做interface的關鍵字,如果非要去模仿接口的概念

可以借助第三方模塊:http://pypi.python.org/pypi/zope.interface

也可以使用繼承,其實繼承有兩種用途

一:繼承基類的方法,並且做出自己的改變或者擴展(代碼重用):實踐中,繼承的這種用途意義並不很大,甚至常常是有害的。因為它使得子類與基類出現強耦合。

二:聲明某個子類兼容於某基類,定義一個接口類(模仿java的Interface),接口類中定義了一些接口名(就是函數名)且並未實現接口的功能,子類繼承接口類,並且實現接口中的功能

class Interface:#定義接口Interface類來模仿接口的概念,python中壓根就沒有interface關鍵字來定義一個接口。
    def read(self): #定接口函數read
        pass

    def write(self): #定義接口函數write
        pass


class Txt(Interface): #文本,具體實現read和write
    def read(self):
        print(‘文本數據的讀取方法‘)

    def write(self):
        print(‘文本數據的讀取方法‘)

class Sata(Interface): #磁盤,具體實現read和write
    def read(self):
        print(‘硬盤數據的讀取方法‘)

    def write(self):
        print(‘硬盤數據的讀取方法‘)

class Process(Interface):
    def read(self):
        print(‘進程數據的讀取方法‘)

    def write(self):
        print(‘進程數據的讀取方法‘)

上面的代碼只是看起來像接口,其實並沒有起到接口的作用,子類完全可以不用去實現接口 ,這就用到了抽象類

抽象類

1 什麽是抽象類

與java一樣,python也有抽象類的概念但是同樣需要借助模塊實現,抽象類是一個特殊的類,它的特殊之處在於只能被繼承,不能被實例化

2 為什麽要有抽象類

如果說類是從一堆對象中抽取相同的內容而來的,那麽抽象類就是從一堆類中抽取相同的內容而來的,內容包括數據屬性和函數屬性。

  比如我們有香蕉的類,有蘋果的類,有桃子的類,從這些類抽取相同的內容就是水果這個抽象的類,你吃水果時,要麽是吃一個具體的香蕉,要麽是吃一個具體的桃子。。。。。。你永遠無法吃到一個叫做水果的東西。

從設計角度去看,如果類是從現實對象抽象而來的,那麽抽象類就是基於類抽象而來的。

  從實現角度來看,抽象類與普通類的不同之處在於:抽象類中只能有抽象方法(沒有實現功能),該類不能被實例化,只能被繼承,且子類必須實現抽象方法。這一點與接口有點類似,但其實是不同的,即將揭曉答案

3. 在python中實現抽象類

#一切皆文件
import abc #利用abc模塊實現抽象類

class All_file(metaclass=abc.ABCMeta):
    all_type=‘file‘
    @abc.abstractmethod #定義抽象方法,無需實現功能
    def read(self):
        ‘子類必須定義讀功能‘
        pass

    @abc.abstractmethod #定義抽象方法,無需實現功能
    def write(self):
        ‘子類必須定義寫功能‘
        pass

# class Txt(All_file):
#     pass
#
# t1=Txt() #報錯,子類沒有定義抽象方法

class Txt(All_file): #子類繼承抽象類,但是必須定義read和write方法
    def read(self):
        print(‘文本數據的讀取方法‘)

    def write(self):
        print(‘文本數據的讀取方法‘)

class Sata(All_file): #子類繼承抽象類,但是必須定義read和write方法
    def read(self):
        print(‘硬盤數據的讀取方法‘)

    def write(self):
        print(‘硬盤數據的讀取方法‘)

class Process(All_file): #子類繼承抽象類,但是必須定義read和write方法
    def read(self):
        print(‘進程數據的讀取方法‘)

    def write(self):
        print(‘進程數據的讀取方法‘)

wenbenwenjian=Txt()

yingpanwenjian=Sata()

jinchengwenjian=Process()

#這樣大家都是被歸一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read()

print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)

4. 抽象類與接口

抽象類的本質還是類,指的是一組類的相似性,包括數據屬性(如all_type)和函數屬性(如read、write),而接口只強調函數屬性的相似性。

抽象類是一個介於類和接口直接的一個概念,同時具備類和接口的部分特性,可以用來實現歸一化設計

5.7抽象類