前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >到底什么是面向对象编程?

到底什么是面向对象编程?

原创
作者头像
淡定的蜗牛
修改2019-11-18 15:53:36
6780
修改2019-11-18 15:53:36
举报
文章被收录于专栏:Java知己Java知己
Java知己
Java知己

前几天网上看到一个有趣的面试问题:

农场有头大母牛,每年生头小母牛,小母牛五年后生小母牛,问20年后农场一共有多少头牛?(使用面向对象编程思维解答)

这个面试问题让我想到了面向过程与面向对象编程的区别,咱们先简单了解下这两者定义上区别:

面向过程 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。

面向对象 是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

看了定义,是不是感觉还是没明白这两者之间的区别,(我信你个鬼,糟老头子坏的很),

那咱们就用图片来作下对比吧:

Java知己
Java知己
Java知己
Java知己

然后我就写了两套代码来作对比,一套是面向过程编程,一套是面向对象编程。咱们一起来看看这两者这间到底有何区别?

正是金九银十跳槽季,为大家收集了2019年最新的面试资料,有文档、有攻略、有视频。有需要的同学可以来在公众号【Java知己】,发送【面试】领取最新面试资料攻略!

面向过程:

代码语言:java
复制
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;
    }
}    

面向对象:

牛的对象:

代码语言:java
复制
/**
 * 这是头牛
 *
 * @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;
    }
}

农场对象:

代码语言:java
复制
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;
}
}

上帝角色(主宰一切):

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
微信关注Java知己,每天更新技术干货
发送「1024」,免费领取 30 本经典编程书籍。
发送「面试」,领取 BATJ面试资料、攻略。
发送「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()));
}
}

下面是运行结果:

两种方式的运行结果是一致的

代码语言:javascript
复制
第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等一般采用面向过程开发,性能是最重要的因素。 缺点:没有面向对象易维护、易复用、易扩展

面向对象优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护

缺点:性能比面向过程低

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前几天网上看到一个有趣的面试问题:
  • 面向过程:
  • 面向对象:
    • 牛的对象:
      • 农场对象:
        • 上帝角色(主宰一切):
          • 下面是运行结果:
          • 咱们通过代码演示,你感觉到这两者的区别了吗?
          • 结论:面向对象思维可以提升项目的可维护性
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档