一文读懂Java面向对象
  顶级码农   8/6/21 10:57:23 PM
面向对象设计思想早已不是什么新鲜事物,在Java实际项目中也是主流的编程思想。 正是因为Java,C#天然就是支持面向对象的,反而很多童鞋并不能讲清楚什么是面向对象。我们只是这样在用而已...

类和实例

  • 把大象装进冰箱
  • 初识面向对象
  • 类和实例
    • 通俗理解
    • 进一步理解
    • 小试牛刀
  • OOP三大特性
    • 封装
    • 继承
    • 多态
  • 结语
  • 参考

算法+数据结构=程序 ——图灵奖的Pascal之父(Niklaus Wirth)

把大象装进冰箱里

有一天,产品经理给我们提了一个需求:要把大象装进冰箱里。

作为程序员的我们,就会思考把大象装进冰箱里需要几步?

经过流程梳理,我们可以大致列了几个步骤:

  • 第一步,把冰箱门打开。
  • 第二步,把大象装进去。
  • 第三步,把冰箱门关上。

上面每一个步骤,我们都可以定义一个函数,每个函数可以实现一个功能。

所有函数定义好了之后,依次调用就可以了:

  • openTheDoor();
  • pushElephant();
  • closeTheDoor();

至此,我们便轻松愉快的完成了产品经理的需求,然后哼着小曲儿去快乐的玩耍了。

但是,过了两天产品经理又提出了更加变态的需求

  • 我要把大象装微波炉里
  • 我要把狮子也装冰箱里
  • 我要把大象装冰箱,但是门别关,敞着就行
  • 。。。

面对这样“变态”的需求,如果继续使用上面的思路来实现代码功能,将会带来以下问题:

  • 大量“重复”函数
  • 代码可读性变差
  • 不易维护
  • 。。。。

以上就是通常所说的面向过程的编程方式。正是因为面向过程的带来的诸多问题,面向对象的编程思想逐渐流行起来,并在编程界风靡至今。

初识面向对象

没有人比我更懂面向对象。

面向对象起源于1967年在挪威设计的Simula编程语言。该语言拥有类、多态和即成等以往的编程语言没有的优良结构,被称为最早的面向对象编程语言(Object Oriented Programming Language,OOP)。后来艾伦.凯率领的团队开发的smalltalk沿用了该结构,确立了面向对象的概念。 此后,具有相同结构的C++、Objective-C、Java、C#和Ruby等诸多编程语言被相继开发出来,并延续至今。

OOP使得大规模时使得大规模的可重(chóng)用构件群的创建成为可能,这些被称为类库或框架。

而创建可重用构件群时使用的固定设计思想被提炼成设计模式。(《面向对象是怎样工作的(第2版)》)

面向对象的基本思想就是重点关注各个构件,提高构件的独立性、重用性,把构件组合起来,实现系统整体的功能。当程序发生修改时,能够将影响范围降到最低。

对象就是对事物的一种抽象描述。 现实世界中的事物,都可以用【属性】和【能力】来描述。

回到上面产品经理的将大象装进冰箱需求,用面向对象来实现,我们会先定义一个冰箱对象,它的【属性】就是当前的冷冻温度,【能力】就是开门、关门。还有一个大象对象,它的【属性】可以是大象的智商、体积。然后我们依次:

  • 向冰箱下达开门的命令。
  • 向冰箱下达存储大象的命令。
  • 向冰箱下达关门的命令。

所以,当我们将程序构件化之后,一旦遇到“我要把大象装冰箱,但是门别关,敞着就行”这样的变态需求,代码不用大改,只需要将先前定义好对象和能力按照新的需求组合即可。

面向过程和面向对象思想的区别

  • 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了
  • 面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

类和实例

类就是指一类事物,对象就是指这类事物中的某个具体的个体。

通俗的解释

类是指一类事物,类是一种归纳和总结,是一种概括,是一个抽象的概念。

比如:我们把那些具有一定知名度、一定名气的人物称之为明星,说白了,类就是对一些具有相同特性的事物进行的归纳和总结。

再比如:我们把那些用胶片或存储卡记录的人物故事影像统称为电影,所以类就是对一些具有相同特性的事物进行的归纳和总结。

你最喜欢的明星是谁? 周杰伦。

这里,明星就是类,周杰伦就是实例。

书面解释

指类型,实例指具体事物

是面向对象的最基本的结构,与其对应

类的英文是class,含义是"种类","类型"等"同类的集合"。实例的英文是instance,含义是"具体的事物"。

比如,

  • 车: 小汽车,大卡车,越野车...
  • 国家:中国、美国、韩国...
  • 运动员:姚明、马龙、张倩...

编程示例

面向对象本质上不是一门技术而是一种思想。

面向对象本身不是一门技术而是一种思想。只有转变了思想,你才能在日常编程中应用自如。

这里依然沿用“把大象装进冰箱”需求,从需求中分析出有两个具体的事物大象冰箱,抽出两个对象


/**
 * Description: 大象类
 */
@Data
public class Elephant {

    private Object head;//
    private List<Object> feets;//四肢
    private Object body;//躯干
    private Object tail;//尾巴

    public String toString(){
        return "大象";
    }
}

/**
 * Description: 冰箱类
 */
@Data
public class Fridge {

    /**
     * 存储
     */
    public  void store(Object obj)
    {
        System.out.println(""+obj.toString()+"放进冰箱");
    }

    /**
     * 开门
     */
    public  void  openTheDoor()
    {
        System.out.println("开门");
    }

    /**
     * 关门
     */
    public  void  closeTheDoor()
    {
        System.out.println("关门");
    }
}

Java使用具体的事物,需要通过new关键字来创建这个事物的具体实例。

我们可以方便的利用Springboot来写一个单元测试:

1.实例化对象


//实例化一头大象
Elephant elephant=new Elephant();


//实体化一个冰箱
Fridge fridge=new Fridge();

2.调用冰箱的功能

fridge.openTheDoor();
fridge.store(elephant);
fridge.closeTheDoor();

执行结果如下:



面向对象的抽取心得

1、先按照名词提炼问题领域中的对象

2、对对象进行描述,其实就是在明确对象中应该具备的属性和功能

3、通过new的方式就可以创建该事物的具体对象

4、通过该对象调用它以后的功能。

OOP三大特性

面向对象思想有三大特性,即封装、继承与多态。三大特性是面向对象编程的核心,对于初学者务必加强对三大特性的理解与领会。

封装

举个例子吧,现代人都爱点外卖。你点一份回锅肉,然后外卖小哥给你送来的时候,已经是打包好的热乎的成品。如果你是自己做的话,需要上菜市去买肉,豆瓣酱,食用油,辣椒等。而外卖营隐藏了这些工序和细节,这就封装。

封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界它的内部细节是隐藏的,暴露给外界的只是它的访问方法。

是否暴露给外部,是通过访问修饰符控制,Java类中常用的访问修饰符如下:

访问控制
修饰符当前类同一包内子孙类(同一包)子孙类(不同包)其他包
publicYYYYY
protectedYYYY/NN
defaultYYYNN
privateYNNNN

继承

比如, 前面产品经理提出了狮子也装冰箱里这样的需求,于是我们提取出狮子对象。


/**
 * Description: 狮子对象
 */
public class Lion {
    private Object head;//
    private List<Object> feets;//四肢
    private Object body;//躯干
    private Object tail;//尾巴

    public String toString(){
        return "狮子";
    }
}

按照面向对象的思想我们很快就写出了狮子类。

但是,不妨再观察一下,大象狮子两个类是不是几乎一样,代码似乎有点重复啊~

能不能将不同类中相同的部分抽取出来公用呢? 继承特性就能做到。

继承要解决的就是代码重用的问题,利用继承性可以从已有的类继续派生出新的子类,也可以利用子类扩展出更多的功能。

大象狮子都属于动物,因此在两个对象的基础上我们可以在抽象一个动物对象,然后大象狮子都继承自动物。

动物类


/**
 * Description: 动物
 */
@Data
public class Animal {

    private Object head;//
    private List<Object> feets;//四肢
    private Object body;//躯干
    private Object tail;//尾巴
}

大象类继承自动物类

/**
 * Description: 大象类
 */
@Data
public class Elephant  extends  Animal{

    public String toString(){
        return "大象";
    }
}

狮子类继承自动物类

/**
 * Description: 狮子对象
 */
public class Lion  extends  Animal{
    public String toString(){
        return "狮子";
    }
}

//实例化一头狮子
Animal lion=new Lion();

//实体化一个冰箱
Fridge fridge=new Fridge();
fridge.store(lion);
fridge.store(lion);
fridge.closeTheDoor();

多态

多态是同一个行为具有多个不同表现形式或形态的能力

还是借用上面的例子来探讨,比如产品经理说动物关进冰箱之前要先叫一声,主人会根据叫声类判断关进去的是什么动物。

动物都有叫的功能


/**
 * Description: 动物
 */
@Data
public class Animal {

    private Object head;//
    private List<Object> feets;//四肢
    private Object body;//躯干
    private Object tail;//尾巴

    public void Cry()
    {
        System.out.println("我被关进了冰箱!");
    }
}

但是不同动物叫声不同,所以需要增加各自叫的方法


/**
 * Description: 狮子对象
 */
public class Lion  extends  Animal{

    // 覆盖(重写)方法
    public void cry() {
        System.out.println("~");
    }

    public String toString(){
        return "狮子";
    }
}\


/**
 * Description: 大象类
 */
@Data
public class Elephant  extends  Animal{

    // 覆盖(重写)方法
    public void cry() {
        System.out.println("~");
    }

    public String toString(){
        return "大象";
    }
}

测试用例走一波



以上我们通过编程实现了,不同的动物有各自的叫法,这就是多态的简单实现。

多态的好处

  • 可替换性(substitutability)。多态对已存在代码具有可替换性。
  • 可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。

结语

面向对象设计思想早已不是什么新鲜事物,在Java实际项目中也是主流的编程思想。

正是因为Java,C#天然就是支持面向对象的,反而很多童鞋并不能讲清楚什么是面向对象。我们只是这样在用而已...

Notes: 尽管大牛们都倡导面向对象,但并不是说面向过程就不能使用。实际项目中,还是要根据需求和场景来选择,面向对象和面向对象都是解决问题的方式,二者并不冲突。

如果本文对您有帮助,欢迎点赞支持!

参考

版权声明: 本文为智客工坊「顶级码农」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。