浅谈面向对象(三大特点)

219 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

背景

问题:程序中如果保存大量的数据,而大量数据如果零散的随意管理,极容易出错,而且不方便使用。
解决:面向对象编程
先使用一个个的对象结构集中存储现实中事物的属性和功能,然后,再按需使用不同对象中的不同属性和功能,这就是面向对象编程。
优点:及其便于大量数据的维护。
如何使用面向对象:
三步/三大特点:封装、继承、多态。

封装

什么是封装

创建一个对象,集中保存现实中一个事物的属性和功能,将零散的数据封装进对象结构中,极其便于大量数据的维护,只要使用面向对象开发时,第一步都是先封装各种各样的对象的结构备用。
一句大白话概括:创建一个新对象,里面保存着属性和功能方法,就是归类

如何封装对象

3种方式:

  • 直接声明var obj={属性名:'',方法名:function(){...}} ;
    如何访问对象中的成员:对象名.属性名 ,对象名.方法名。
let obj={
 name:'静静',
 age:18,  
 say:function(){
  console.log(this.name);
 }
}
console.log(obj.name,obj.say());
  • new Object()
    var obj=new Object();obj.属性名='';obj.方法名=function(){...};

  • 构造函数 前两种方式,有个问题是:每次只能创建一个对象,如果要创建的对象很多的话,就会很麻烦,出现大量的重复代码,因此,第三种方式就解决的这个问题,那就是构造函数
    解决:
    只要想反复创建多个相同结构,只是内容(功能,元素值)不同的对象时,都要使用构造函数
    定义构造函数:

var 类型名=function(形参1,形参2,...){
 //将来要加入新对象中规定的属性
 this.属性名=形参1,  
 this.xxx=xxx,
 this.方法名=function(){
 ...this.属性名...
 }
}

使用构造函数反复创建多个相同结构的对象 :

var 对象名=new 类型名(实参1,实参2,...);

访问对象属性/数组元素

3中方式:

  • 标准:如果下标名和数组名是已知的,对象/数组[已知的属性名或下标名];
  • 简写:如果下标名和数组名是已知的:
  1. 如果下标名是数字,对象/数组[已知的数字下标] ;
  2. 如果下标名是非数字的字符串,对象/数组.已知的属性名] ;
  3. 如果属性名或下标是一个变量,只能用对象/数组[变量],不能用.;

继承

问题:只要将方法定义放在构造函数中,那么,每次new时都会执行function,就会多次创建new Function(),会反复创建相同函数的多个副本浪费内存
解决: 如果发现多个子对象都要使用相同的功能和属性时, 都可以用继承

什么是继承

父对象中的成员,子对象无需重复创建,就可直接使用,就像使用自己的成员一样this.属性名/方法名()
js中继承都是通过原型对象实现的。

什么是原型对象

替所有子对象集中保存共有的属性和方法的父对象

何时使用原型对象

只要发现多个子对象中都需要相同的属性和功能方法时,都可将相同的功能方法和属性集中定义在原型对象中。

如何创建原型对象

不用自己创建,而是在定义构造函数时,程序自动附赠给我们一个空的原型对象。

如何找到原型对象

构造函数中都有一个自带的属性prototype,指向自己配对的原型对象,构造函数.prototype

如何继承

不用自己设置继承关系new自动让新创建的子对象,继承构造函数的原型对象,new自动设置子对象的_ _proto_ _指向构造函数的原型对象。

如何向原型对象添加共有属性和方法

只能强行赋值:
构造函数.prototype.属性名=属性值,构造函数的.propotype.方法名=function(){}

总结

如果用子对象.访问任何成员时,js引擎现在子对象内部查找自有的属性和方法,如果子对象没有,则js引擎会自动用_ _proto_ _ 属性去父对象查找,如果父对象没有,继续在原型链里继续向上查找,如果在父对象中找到了想要的属性和方法,则和访问子对象的方法一样调用。
构造函数中一定不要包含方法的定义,会浪费内存,所有公用的方法都应该集中定义到原型对象中一份,所有子对象共用。

多态

什么是多态

同一个函数,在不同情况下表现出不同的状态。

表现的方式

包括两种方式:

  • 重载overload:同一个函数,输入不同的参数,执行不同的逻辑。
  • 重写override:父对象中的方法属性不想要,自己重新写一个,覆盖父对象的。(推翻、遮挡)。
  1. 什么是重写? 在父对象中定义一个和父对象中的成员同名的自由成员。

  2. 何时使用? 从父对象继承下来的个别成员不好用时,就可以在子对象中定义同名的成员,来覆盖父对象中的同名成员。