一、面向对象编程

从崛起的智人到被苹果砸中的牛顿再到如今的你,一直在思考“这是个怎么样的世界?”

1、世上本没有苹果

看到一张苹果的图片,脑海里天然浮现“图片上的是一个苹果”,为何会称苹果为‘苹果’?java

世界上全部的物质都是客观存在的,基于事物固有的特性,人类用本身方式将其抽象为具体的概念并用一些媒介表达了出来,这些媒体如语言、绘画、手语等。

将客观存在事物抽象为咱们本身的概念,便能方便平常的交流和对事物的研究利用。对事物进行抽象定义的质量越高,咱们使用起来越方便。在平常生活中,当说起到这些事物时咱们对这些事物的特征、功能也老是‘心中有数’。编程

咱们解决问题的能力直接取决于咱们对事物抽象的质量。工具

2、使用计算机来表达事物的抽象

计算机也是咱们表达和使用抽象的一种有效媒介。设计

进行程序设计的目的就是解决实际生活中一些的问题,程序老是和实际息息相关的。将实际问题中元素用计算机的方式来进行抽象定义,而后利用这些抽象来解决问题。这样咱们直面的便问题空间中的抽象,在解决问题是基于问题的结构,而不是基于计算机结构。code

不使用面向对象时,可能写出下面的代码(伪代码):对象

/*将一个用户信息保存到文件*/
userName = "xxxx";
userAge = "18";
userTel = "11111";
fileName = "xxxxxx";
// 保存信息到文件
file = open(fileName);
file.write(userName);
file.write(userAge);
file.write(userTel);
file.close();

这样的代码用户相关信息在码层面并无提现出强烈的相关,他们都只是一个个独立的变量。只有咱们本身知道他们是‘一块儿’的,并实时维护他的关系。在保存信息到文件时,总时要打开、写入、关闭,对于不少个信息就繁琐且复杂。继承

使用面向对象来解决这个问题,先将用户信息抽象出来并将抽象的定义的类放到一个单独的文件中:图片

class UserInfo {
    name;
    age;
    tel;
    FILE_NAME = "xxxxxx";
    
    function saveUserInfo() {
        file = open(FILE_NAME);
        file.write(userName);
        file.write(userAge);
        file.write(userTel);
        file.close();
    }
}

这里,用户的各个信息一目了然的他们是‘一块儿’的,而且将写的操做也进行了抽象封装。在解决问题的代码文件中使用定义好的抽象:it

userUnfo = new UserInfo();
userInfo.name = "xxx";
userInfo.age = 18;
userInfo.tel = "11111";
userinfo.saveUserInfo();

这一部分代码才是咱们真正须要的用来解决问题的代码。这里咱们没必要时刻当心的维护用户信息各个部分是'一块儿'的,在这他们都属于UserInfo的属性,保存文件时也没必要再考虑其实现的细节,这些细节咱们已经作好了封装,在这里只须要使用就行。io

利用计算机来对事物进行抽象并使用即是面向对象编程。

3、面向对象的三个特性

一、封装
将水烧开,咱们须要热水器和电。将水倒入插电的热水器,打开开关将水烧开。在这个过程当中咱们并不关心热水器的具体实现,也不关心电是这产生的等等,这些全部的东西都是“封装”好的,咱们只使用好这些东西就行。

编程来解决这个问题时,何不妨一样先将热水器等的属性和功能进行封装。而后在使用这些封装好的元素来解决问题,就如同实际中同样天然流畅。而不是在每一个步骤都调用计算机相关的特性来实现,这样会让整个问题和计算机的实现混合不清。

类与对象:

面向对象中用类来描述事物的属性和功能,对事物进行抽象即是抽象为一个类。
对象是类的一个具体实例。如某天看到的一只鸟,这只鸟即是鸟类的一个具体实例。

经过定义类将问题空间中元素的进行了封装,而后实例化类的对象来为问题的求解提供服务。

类也是自定义的数据类型:

一个类定义完成后即是一个咱们本身定义的数据类型。像建立内置类型的变量同样建立类的变量(即类的对象),而后操做这些对象。每一个对象都有其类的特性,而每个对象有是独立的一个变量。

生活中使用程序提供的服务来解决问题,而程序的又调用各个对象提供的服务来来实现。这些对象和实际问题中的各个元素同样,经过调用这些元素完成特定的功能来解决问题。对象的调用即是调用对象的方法,每个方法知足了特定的需求。

在面向对象中一切都是对象,每一个对象提供服务或数据给其余对象,对象之间互相调用和传递数据来解决问题

二、继承

一个新类和原有类具备类似的功能,只是添加了部分新功能或部分功能不同,咱们又得从新定义重复的功能,这样显得很麻烦,代码不具有复用性。 这类需求在面向对象中使用继承来处理。

经过继承新的类便具有了原有类的功能和特性的同时又能够进行本身的扩展建立出一个新类。被继承的类称为基类,继承基类的新类称为导出类。一般将一些共性和核心建立为基类,再经过继承来建立新不一样实现的新类。

继承时,导出类继承了基类全部的特性和功能,这也就意味着全部对基类的调用,在导出类中一样也具备并能够调用,如此意味着导出类与基类是同一的类型。但基类与导出类却不是同一类型,由于对导出类添加的新特性基类并不具有。

因此能够将导出类的实例对象赋给基类,做为一个基类对象使用。但这时是并不能够访问导出类的新方法,毕竟导出类同基类是同一类型,但基类同导出类不是同一类型,由于导出类会添加或修改类功能。
三、多态
你有不少部手机,但每一部手机的充电器都是不同的,当其中一部手机须要充电的时,你对助理说“帮我冲下电”,助理天然会去找合适充电器,没必要告诉助理手机是什么型号去找什么样的充电器。

将这些手机进行封装

先将手机共有的特性封装为一个Phone基类,基类包括充电这个共性功能。而后继承这个类并覆盖基类的充电方法,来实现每一类型的充电的具体实现。

生活中咱们说手机充电,这里手机是一个大的类型,但咱们知道该用那个一个充电器。
既然在继承时导出类和基类是同一个类型,那么当咱们把一个派生类对象赋给基类时,对于那些覆盖了基类的功能,一样也应该知道在须要时去调用派生类的实现。

Phone p = new Apple();
p.charge();

经过继承新加了Apple手机的类,而后建立Apple类并将它赋值给了Phone类型,那么当调用充电时天然应该去调用Apple本身的充电方法。

根据对象具体实现取去查找其对应的方法,这就是多态。

固然多态对于产生覆盖的方法才有意义,毕竟虽然导出类和基类能够视为统一类型是由于导出类继承了基类的所有,但基类却并不拥有导出类的新特性。因此在一个基类对象上调用导出类的新功能者并无什么意义,也不符合现实。毕竟在生活中咱们能够说交通工具载货,但并不会说交通工具起飞,而是说飞机起飞。但对于导出类覆盖基类的方法,导出类和基类都有这样功能,只是实现不一样,因此多态在此时显得有意义且必要。

*建议

  1. 若是新的类只是单纯的继承而没有添加任何新的特性,这就意味着导出类和基类属性和方法彻底相同,然而这样并无什么特别的意义,建议导出类与基类存在必定的差别。

产生差别:在导出类中添加新的特性或覆盖

  1. 在须要时才使用继承,到处使用继承是不合理的且会致使设计过度复杂和难以维护。是否使用继承:导出类与基类是否为“是一个的关系”,并具备意义,列如一个圆是一个几何”
相关文章
相关标签/搜索