到底什么是面向對象編程?


面向對象編程?你說的是看着女朋友進行編程嗎?

注釋:沒有對象怎辦?

 

前幾天網上看到一個有趣的面試問題:

農場有頭大母牛,每年生頭小母牛,小母牛五年后生小母牛,年齡大於15便死亡💀,問20年后農場一共有多少頭牛?(使用面向對象編程思維解答)

 

這個面試問題讓我想到了面向過程與面向對象編程的區別,咱們先簡單了解下這兩者定義上區別:

  • 面向過程 就是分析出解決問題所需要的步驟,然后用函數把這些步驟一步一步實現,使用的時候一個一個依次調用就可以了。
  • 面向對象 是把構成問題事務分解成各個對象,建立對象的目的不是為了完成一個步驟,而是為了描敘某個事物在整個解決問題的步驟中的行為。

看了定義,是不是感覺還是沒明白這兩者之間的區別,(我信你個鬼,糟老頭子壞的很),

那咱們就用圖片來作下對比吧:

然后我就寫了兩套代碼來作對比,一套是面向過程編程,一套是面向對象編程。咱們一起來看看這兩者這間到底有何區別?

面向過程:

public static void main(String[] args){
        //所有牛的集合
        List<Integer> cowAgeList = new ArrayList<>();
        //添加第一只5歲的大母牛
        cowAgeList.add(5);
        //循環20年
        for(int i=0;i<20;i++){
            int count_new = 0;//當年新生數量
            int count_dead = 0;//當年死亡數量
            //當年新生的集合
            List<Integer> cowChild = new ArrayList<>();
            //遍歷當年所有母牛,年齡自增、看看生不生
            for(int index=0;index<cowAgeList.size();index++){
                //新的一年,加一歲
                int age = cowAgeList.get(index) + 1;
                //將新年齡設置回集合中
                cowAgeList.set(index,age);
                //看下這頭母牛是否該GameOver了
                if(age>15){
                    count_dead++;
                    continue;
                }
                //試下生只小母牛吧,生不生的出來說不准(看年齡)
                Integer cowNew = produce(age);
                //哎,如果還生出來了,那咱們就挪窩到當年新生牛犢(不是牛肚哈)集合中
                if(cowNew!=null){
                    count_new++;
                    //這里有個小細節,容易出錯,我開始就想,直接把新生小母牛放到所有牛集合中不就行了,
                    //為啥非得先放到當年新生小母牛集合中,后面再統一放到所有牛集合中,你先想下這個問題
                    //咱們后面再說為什么需要這么做
                    cowChild.add(cowNew);
                }
            }
            //今年生牛這個過程結束了,然后再把新生小母牛都放到所有牛集合中
            cowAgeList.addAll(cowChild);
            //我們上面說到為什么不直接把新生的小母牛直接放到所有牛集合中
            //因為如果把新新生小母牛直接放到所有牛集合中,
            // 那么當年這個新生的小母牛就會在后面的遍歷中再次遍歷一次
            //新生的小母牛年齡是0吧,直接放到所有牛集合中,
            // 新生小母牛年齡就也自增了,這不是我們想要的
            System.out.println(String.format("第%d年,出生:%d,死亡:%s",i,count_new,count_dead));
        }

        //使用迭代器移除已經死亡的母牛,剩下的就是20年后所有存活的母牛了
        Iterator<Integer> iterator = cowAgeList.iterator();
        while(iterator.hasNext()){
            if(iterator.next().intValue()>15){
                iterator.remove();
            }
        }
        System.out.println(String.format("20年后農場存活牛的數量為:%d",cowAgeList.size()));
    }

    /**
     * 根據母牛年齡生產小母牛
     * @param age-母牛年齡
     * @return 新生小牛年齡(null表示沒有生)
     */
    private static Integer produce(int age){
        if(age>=5 && age<=15){
            return 0;
        }
        return null;
    }

 

面向對象:

牛的對象:

/**
 * 這是頭牛
 *
 * @Date: 2019/7/26
 */
public class Cow {
    /**
     * 年齡
     */
    private int age;

    /**
     * 是否活者
     */
    private boolean alive = true;

    public Cow(int age) {
        this.age = age;
    }

    /**
     * 生牛動作
     * 是否能生的出來,得看年齡
     *
     * @return
     */
    public Cow produceCow() {
        if (this.age < 5 || !this.isAlive()) {
            return null;
        }
        return new Cow(0);
    }

    /**
     * 每年長一歲
     */
    public void addAge() {
        this.age += 1;
        //年齡大於15就掛掉
        if (this.age > 15) {
            this.alive = false;
        }
    }

    public boolean isAlive() {
        return alive;
    }
}

 

農場對象:

import java.util.ArrayList;
import java.util.List;

/**
 * 這就是一個農場
 *
 * @Date: 2019/7/26
 */
public class Farm {
    //農場里所有牛的集合
    private List<Cow> cowList = new ArrayList<>();

    public Farm() {
    }

    public List<Cow> getCowList() {
        return cowList;
    }

    public void setCowList(List<Cow> cowList) {
        this.cowList = cowList;
    }
}

 

上帝角色(主宰一切):

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 微信關注[Java知己],每天更新技術干貨
 * 發送「1024」,免費領取 30 本經典編程書籍。
 * 發送「Group」,與 10 萬程序員一起進步。
 * 發送「JavaEE實戰」,領取《JavaEE實戰》系列視頻教程。
 * 發送「玩轉算法」,領取《玩轉算法》系列視頻教程。
 */
public class Main {

    /**
     * 這里是上帝角色,控制着一切
     * @param args
     */
    public static void main(String[] args) {
        //實例化農場
        Farm farm = new Farm();
        //實例出來第一頭母牛
        Cow cow = new Cow(5);
        //將第一只牛放到農場里面
        farm.getCowList().add(cow);

        for(int year=0;year<20;year++){
            int count_dead = 0;//死亡數量
            List<Cow> cowChilds = new ArrayList<>();
            for(Cow cowTemp:farm.getCowList()){
                cowTemp.addAge();
                Cow child = cowTemp.produceCow();
                if(child!=null){
                    cowChilds.add(child);
                }
                if(!cowTemp.isAlive()){
                    count_dead++;
                }
            }
            farm.getCowList().addAll(cowChilds);
            System.out.println(String.format("第%d年,出生:%d,死亡:%d",year,cowChilds.size(),count_dead));
        }

        //移除已經死亡的牛
        Iterator<Cow> iterator = farm.getCowList().iterator();
        while(iterator.hasNext()){
            if(!iterator.next().isAlive()){
                iterator.remove();
            }
        }
        System.out.println(String.format("20年后農場存活牛的數量為:%d",farm.getCowList().size()));
    }
}

 

下面是運行結果:(兩種方式的運行結果是一致的)

第0年,出生:1,死亡:0
第1年,出生:1,死亡:0
第2年,出生:1,死亡:0
第3年,出生:1,死亡:0
第4年,出生:1,死亡:0
第5年,出生:2,死亡:0
第6年,出生:3,死亡:0
第7年,出生:4,死亡:0
第8年,出生:5,死亡:0
第9年,出生:6,死亡:0
第10年,出生:7,死亡:1
第11年,出生:10,死亡:1
第12年,出生:14,死亡:1
第13年,出生:19,死亡:1
第14年,出生:25,死亡:1
第15年,出生:32,死亡:1
第16年,出生:41,死亡:2
第17年,出生:54,死亡:3
第18年,出生:72,死亡:4
第19年,出生:96,死亡:5
20年后農場存活牛的數量為:391

 

咱們通過代碼演示,你感覺到這兩者的區別了嗎?

面向對象編程對於勻我們來說更容易理解業務的邏輯性

就算是自己寫的代碼,過上一段時間,自己再去看,是不是也是一頭霧水,得好好看上一段時間才能理得清楚某塊代碼的業務邏輯是怎樣的

用下面這張圖來形容,偶然間看到自己多年前寫的代碼,我覺得很貼合實際

注釋:偶然間看到自己多年前寫的代碼

結論:面向對象思維可以提升項目的可維護性

最后讓我們做下總結:

面向過程

優點:性能比面向對象高,因為類調用時需要實例化,開銷比較大,比較消耗資源;比如單片機、嵌入式開發、 Linux/Unix等一般采用面向過程開發,性能是最重要的因素。
缺點:沒有面向對象易維護、易復用、易擴展

 

面向對象

優點:易維護、易復用、易擴展,由於面向對象有封裝、繼承、多態性的特性,可以設計出低耦合的系統,使系統 更加靈活、更加易於維護
缺點:性能比面向過程低

 


 

正是金九銀十跳槽季,為大家收集了2019年最新的面試資料,有文檔、有攻略、有視頻。有需要的同學可以在公眾號【Java知己】,發送【1024】領取30本Java經典開發書籍,發送【面試】領取最新面試資料攻略!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM