32

面试官:淦!0202年你还不知道面向对象?

 3 years ago
source link: http://www.cnblogs.com/viyoung/p/13128956.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

2020年6月13日 多云转暴雨⛈️

I'm sad,tired,negative,powerless,miss,lonely fine :)

那你回去等通知吧

面试官:我看你简历上说,你的主要编程语言是 Java ,偶尔也用 Python ,那么你可以说一下这两个的相同点在什么地方吗?

山禾:它们都是高级程序设计语言,都是面向对象的语言。

面试官:那你讲讲你是怎么理解面向对象的吧。

山禾:emmm。。封装,继承,多态是面向对象的三大特征。

面试官:还有其他要补充的吗?

山禾:没了

面试官: 那你回去等通知吧

是什么

痛定思痛,挫折只会让我变得更强,奥利给!下面开始进入正文,首先我们需要知道面向对象是什么?

面向对象,顾名思义,是面向 对象 ,也就是说单身狗是不配使用面向对象的编程语言的(当然只是开个玩笑,逃)。

对象,就是把现实世界中的 实物 映射抽象到虚拟世界中,把实物的属性和行为,通过代码的方式表达出来。然后通过设计对象的 数据结构 (属性),然后使用 算法 进行行为的模拟(方法),就完成了从现实到虚拟的一个映射。

实体 对象 类 属性 数据结构 变量 行为 算法 方法

与面向对象经常拿来对比的就是面向过程编程,那么他们之间的区别在什么地方呢?

面向过程和面向对象

面向过程编程,打个比方,我们买过的一般的玩具(变形金刚),我们必须要按照它说明书上的步骤,一步一步的去组装,才能得到最后的玩具,如果我们想要一个新的玩具,就要去商场买一个新的,然后按照说明书的顺序一步一步的组装。

而面向对象编程,就可以理解为积木,没有一个固定的拼装方式,我们可以发挥自己的想象力,去自由的拼装和组装,同样的模块在不同的地方可以起到不同的作用(多态),一块儿积木就是一个最小的单位,我们不用去关心积木是怎么造的(封装)。也可以用多个对象组装起来去拼装成一个新的对象(继承)。大大的方便了我们的设计,不再拘泥于过程,极大程度上的放飞了生产力和效率。

为什么

我们刚刚已经了解了面向对象是什么,下面我们来说一下,为什么要用面向对象编程

  1. 首先从理解角度上来说,它符合我们对现实世界的认知习惯,更容易去理解、实现和设计我们的需求。

  2. 其次从软件设计的角度上来说,行为的实现对于外部是完全封闭的,只需要提供对应的接口就可以获得相应的结果,降低了代码与代码之间的耦合度。符合我们高内聚,低耦合的设计理念。 优雅,客观,层次分明 ,像积木一样,可以方便的实现插拔和维护,对象组合而成的模块化和服务化,更是大大扩展了系统的伸缩性,便于 维护、扩展和复用 。这也是为什么越来越多的编程语言选择向这个方向去靠拢( TypeScript说的就是你

怎么用

刚刚我一直忍住,没有去提面向对象的三大特性:封装、继承和多态,我相信我们有一些经验的开发人员来说,这三个词语是再熟悉不过了。下面,我通过代码的方式,来看看这三个特性在代码中的模拟应用。

封装

@Data
public class Uzi {

// 选手类型
private String type;
// 选手最擅长英雄
private String bestHero;
// 选手状态
private Status status;

public void play() {
status.say();
}
}

public class Status {
public void say(){}
}

上面是一段非常简单的代码,我定义了一个很简单的类,里面的 nametypebestHero 对于我们来说都是一个包装在盒子里的东西。比如:

    Uzi uzi = new Uzi();
uzi.setType("ADC");
uzi.setBestHero("孙尚香");

我们看到的Uzi可能就是一个主玩孙尚香的职业ADC选手(:dog:狗头保命,我啥都不知道),他怎么玩的,我们不需要知道,我们只需要知道他这样的一名选手就可以了。这就是封装的魅力:

  1. 隐藏了实现的细节,提供对外的访问方式。

  2. 外部如果想要访问,必须经过这个方法。

继承

看完了封装,下面我们来看继承,我们分别用三个状态去继承Status类:

public class ShunFeng extends Status {

@Override
public void say(){
System.out.println("顺风狂小狗");
}
}
public class NiFeng extends Status {

@Override
public void say(){
System.out.println("逆风简自豪");
}
}

public class JueJing extends Status {

@Override
public void say(){
System.out.println("绝境Uzi");
}
}

关键字 extends 表示正在构造的新类派生于一个已经存在类。这个已经存在的类被称为父类(超类,基类);新创建的类被称为子类。在通过扩展父类定义子类的时候,仅仅需要指出子类和父类的不同之处。因此在设计类的时候,应该将通用的方法放在父类中,而将具有特殊用途的方法放在子类中。

我们只是在父类 Status 中定义了say方法,然后三种不同的类去继承这个类,然后实现方法,这样就体现出了面向对象在设计上的可扩展性,但是需要注意的是,继承会破坏封装,我们需要谨慎使用,尽量使用一些设计模式去避免继承,合理使用,才能体现出它的优势~

说完了继承,接下来就要去说多态了。

多态

在说多态之前,我们先来看一下代码:

public class Test {
public static void main(String[] args) {
//uzi1
Uzi uzi1 = new Uzi();
ShunFeng shunFeng = new ShunFeng();
uzi1.setStatus(shunFeng);
//uzi2
Uzi uzi2 = new Uzi();
NiFeng niFeng = new NiFeng();
uzi2.setStatus(niFeng);
//uzi3
Uzi uzi3 = new Uzi();
JueJing jueJing = new JueJing();
uzi3.setStatus(jueJing);

//uzis
Uzi[] uzis = {uzi1,uzi2,uzi3};
// 多态
for (Uzi uzi : uzis) {
uzi.play();
}
}
}

运行程序的结果: JZbIVfi.jpg!web (TMD,泪目,:older_man:青结)

所谓的多态就是一个对象变量(比如上文中的status变量)可以指示多种实际类型的现象(比如status既可以引用Status对象,也可以引用它的子类ShunFeng对象)被称为 多态 。在运行时候能够自动地选择调用哪个方法的现象被称为 动态绑定 ,上面打印出的语句,就说明了这一点。

后续

原来我们天天挂在口边的面向对象,其实某种程度上来说, 更像是一种哲学,一种计算机科学发展的自然规则。

如果你有学到,请给我点赞:+1:+关注,这是对一个:fist:坚持原创作者的最大支持!我是山禾,千篇一律的皮囊,万里挑一的灵魂,一个不太一样的写手。

世事洞明皆学问,人情练达即文章。

RfUrQ32.jpg!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK