抽象

在讲解面向对象编程的三大特征前,我们先了解什么叫抽象,在定义一个类时候,实际上就是把一类事物的共有的属性和行为提取出来,形成一个物理模型(模板)。这种研究问题的方法称为抽象。

封装

什么是封装?

封装就是把抽象出来的属性和对属性的操作封装在一起,属性被保护在内部,程序的其它部分只有通过授权的操作(函数),才能对属性进行操作。

封装--访问控制修饰符

电视机的开关,对音量,颜色,频道的控制是公开的,谁都可以操作,但是对机箱后盖,主机板的操作却不是公开的,一般由专业维修人员来玩。那么在js中如何实现这种类似的控制呢?请看下例:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
function Person(name, agei, sal) {
this.name = name;//公开属性
var age = agei;//私有属性
var salary = sal;//私有属性
//在类中如何定义公开方法(特权方法),私有方法(内部方法)
//如果我们希望操作私有的属性,则可用公开方法实现
this.show = function() {
window.alert(age+" "+salary);
}
//私有方法,可以访问对象的属性
function show2() {
window.alert(age+" "+salary);
}
}
var p1 = new Person("sp", 20, 50000);
window.alert(p1.name);
p1.show();
p1.show2();//Uncaught TypeError: p1.show2 is not a function
</script>
</head>
<body> </body>
</html>

js提供有以下几种控制方法和属性的访问权限:

  1. 公开级别:对外公开
  2. 私有级别:类本身可以访问,不对外公开

通过prototype给所有对象添加方法,但是这种方法不能访问私有变量和私有方法。

例,

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
function Person() {
this.name = "abc";
var age = 90; this.abc = function() {
window.alert("abc()");
} function abc2() {
window.alert("abc2()");
}
} Person.prototype.fun1 = function() {
window.alert(this.name);// ok
//window.alert(age);// no ok Uncaught ReferenceError: age is not defined
//window.alert(this.age);// 输出undefined
this.abc();// 注意:不要漏掉this
//abc2();// no ok
}
var p1 = new Person();
p1.fun1(); fun1();// Uncaught ReferenceError: fun1 is not defined
</script>
</head>
<body> </body>
</html>

特别注意:类名.prototype.函数名=function(){}这个也称为后置绑定。

 继承

1、为什么需要继承?

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
function MidStu(name, age) {
this.name = name;
this.age = age;
this.show = function() {
window.alert(this.name+" "+this.age);
}
//计算学费
this.payFee = function(money) {
window.alert("应交"+money*0.8);
}
}
function Pupil(name, age) {
this.name = name;
this.age = age;
this.show = function() {
window.alert(this.name+" "+this.age);
}
//计算学费
this.payFee = function(money) {
window.alert("应交"+money*0.5);
}
}
</script>
</head>
<body> </body>
</html>

问题:以上示例代码冗余。

解决方案:抽象出一个学生类,即把中学生和小学生的共性取出。如下例:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
//怎么解决代码冗余-->继承
//抽象出一个学生类,即把中学生和小学生的共性取出
function Stu(name, age) {
this.name = name;
this.age = age;
this.show = function() {
window.alert(this.name+" "+this.age);
}
}
function MidStu(name, age) {
/*
window.alert(Stu);
this.stu = Stu;这一句其实相当于下面这句
this.stu = function Stu(name, age) {
this.name = name;
this.age = age;
this.show = function() {
window.alert(this.name+" "+this.age);
}
};
*/
this.stu = Stu;
this.stu(name, age);//JS中实际上是通过对象冒充,来实现继承,这句话不能少,因为js是动态语言(执行的时候才分配空间),如果不执行它则不能实现继承 //MidStu可以覆盖Stu父类的show
/*
this.show = function() {
window.alert("MidStu show();");
}
*/
}
function Pupil(name, age) {
this.stu = Stu;
this.stu(name, age);
}
var midStu = new MidStu("阿昀", 20);
//window.alert(midStu.name);// undefined
//midStu.show();//Uncaught TypeError: midStu.show is not a function
midStu.show();
</script>
</head>
<body> </body>
</html>

继承--解决之道:

继承可以解决代码利用,让我们的编程更加靠近人类思维,当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类(比如刚才的Stu),在父类中定义这些相同的属性和方法,所有的继承类不需要重新定义这些属性和方法,js中没有extends关键字,它可以通过如下方式实现继承。

  1. 对象冒充
  2. call及apply

继承--小结:

  1. js可以实现多重继承
  2. Object类是js所有类的基类

 方法重载(overloading)及覆盖(overriding)

简单的说:方法重载就是类的同一种功能的实现方式,到底采用哪种方式,取决于调用者给出的参数。

js不支持重载操作(即不可以通过参数的个数来决定调用哪个函数,但是因为js本身支持可变参数,所以,它可以看成天然支持重载)。如下例:

function abc() {
if(argument.length = ...) {// 通过参数个数来判断执行哪个代码 } else if(...) { } ....
}

因为javascript中的方法本身就是一个带可变参数的,通过在方法体内检测方法的参数情况,来实现重载的效果。[调用最后那个方法]

覆盖,也称为改写,就是指子类中定义的方法替换掉父类的方法。(案例说明)

多态 

所谓多态,就是指一个引用(类型)在不同情况下的多种状态,在java中多态是指通过指向父类的引用,来调用在不同子类中实现的方法。

js实际上是无态的,是一种动态语言,一个变量的类型是在运行的过程中由js引擎来决定的,所以说js天生就支持多态。

一个多态的经典案例:

代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
function Master() {
//给动物喂食
this.feed = function(animal, food) {
window.alert(animal.constructor);
document.writeln("主人给"+animal.name+"喂"+food.name);
}
}
//写一个食物类
function Food(name) {
this.name = name;
//...
}
function Fish(name) {
this.food = Food;
this.food(name);
}
function Bone(name) {
this.food = Food;
this.food(name);
}
function TaoZi(name) {
this.food = Food;
this.food(name);
}
//动物
function Animal(name) {
this.name = name;
//....
}
function Cat(name) {
this.animal = Animal;
this.animal(name);
}
function Dog(name) {
this.animal = Animal;
this.animal(name);
}
function Monkey(name) {
this.animal = Animal;
this.animal(name);
} var cat = new Cat("小猫咪");
var dog = new Dog("小狗");
var fish = new Fish("小鱼");
var bone = new Bone("骨头"); var master = new Master();
master.feed(cat, fish);
master.feed(dog, bone);
master.feed(new Monkey("小猴"), new TaoZi("水蜜桃"));
</script>
</head>
<body> </body>
</html>

闭包

老韩讲闭包时到底有多随意啊!我相信讲闭包,又得开一个系列了。所以这里仅作初步了解。

闭包的解释:

  1. 闭包和垃圾回收机制GC是相关联的
  2. 闭包实际上是在涉及到一个对象的成员属性,何时被GC处理的问题
  3. 怎样才能对对象的属性形成一个闭包

如下例:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
/*闭包(closure)——讨论的(回收时机问题)是什么时候回收什么时候不回收*/
function A() {
var i = 0;
function b() {
window.alert(i++);
}
return b;
}
//闭包<--->GC
A();//此时内存中会有一个i的存储空间,被GC处理(是不是立马呢?至少会被当作垃圾,GC会认为被处理了)
var c = A();//这种用法,GC不会把i当作垃圾
// c();
window.alert("aa");
//...
//...
c();//输出0
c();//输出1,从而证明i变量被闭包
</script>
</head>
<body> </body>
</html>

JS面向(基于)对象编程--三大特征的更多相关文章

  1. js面向(基于)对象编程—类(原型对象)与对象

    JS分三个部分: 1. ECMAScript标准--基础语法 2. DOM  Document Object Model 文档对象模型 3. BOM  Browser Object Moldel 浏览 ...

  2. JS面向(基于)对象编程--构造方法(函数)

    构造函数(方法)介绍 什么是构造函数呢?在回答这个问题之前,我们来看一个需求:前面我们在创建人类的对象时,是先把一个对象创建好后,再给他的年龄和姓名属性赋值,如果现在我要求,在创建人类的对象时,就直接 ...

  3. JavaScript学习总结(九)——Javascript面向(基于)对象编程

    一.澄清概念 1.JS中"基于对象=面向对象" 2.JS中没有类(Class),但是它取了一个新的名字叫“原型对象”,因此"类=原型对象" 二.类(原型对象)和 ...

  4. JavaScript学习总结(5)——Javascript面向(基于)对象编程

    一.澄清概念 1.JS中"基于对象=面向对象" 2.JS中没有类(Class),但是它取了一个新的名字叫"原型对象",因此"类=原型对象" ...

  5. js面向(基于)对象编程-三大特征

    ①抽象 js提供以下几种控制方法和属性的访问权限: (1)公开级别:对外公开 (2)私有级别:类本身可以访问,不对外公开 案例如下所示: function Person(name,age,sal){ ...

  6. JavaScript基于对象编程

    js面向对象特征介绍 javascript是一种面向(基于)对象的动态脚本语言,是一种基于对象(Object)和事件驱动(EventDirven)并具有安全性能的脚本语言.它具有面向对象语言所特有的各 ...

  7. python---面对对象的三大特征

    一.三大特征 面对对象的三大特征:继承.多态和封装,继承在面向对象类的创建中非常常见. 1.继承 为什么会有继承,当我们要创建一个新类的时候,发现他有很多属性或者反法都和我们另一个类的方法相同,这时我 ...

  8. 《Essential C++》读书笔记 之 基于对象编程风格

    <Essential C++>读书笔记 之 基于对象编程风格 2014-07-13 4.1 如何实现一个class 4.2 什么是Constructors(构造函数)和Destructor ...

  9. Python学习day24-面向对象的三大特征之继承

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

随机推荐

  1. Paragon NTFS for Mac免费获取官方赠送正版.更新获取ntfs for mac 14方法

    Paragon NTFS for Mac免费获取官方赠送正版,没有这个软件的朋友赶紧收下.获取地址http://www.paragon-drivers.com/cn/ntfs-mac-free/ntf ...

  2. Swift Explore - 关于 Swift 中的 isEqual 的一点探索

    在我们进行 App 开发的时候,经常会用到的一个操作就是判断两个对象是否相等.比如两个字符串是否相等.而所谓的 相等 有着两层含义.一个是值相等,还有一个是引用相等.如果熟悉 Objective-C ...

  3. 目前国内外主流的linux发行版本

    1.linux其实是基于unix发展而来的,还有mac os也是类unix操作系统 2.目前主流的linux发行版本主要有:红帽系列(中国大陆,美洲地区,发源于美国),suse系列(欧洲地区流行,发源 ...

  4. 基于.net mvc的校友录(四、系统结构图)

    这是整个系统结构的预览,话不多说,给个图: 本网站努力为每个人提供一个有效的校友录系统,为参与者提供一个简单有效的交流互动的平台,操作上要求简单.高效,性能上要求稳定.可扩展.在对同类网站系统进行了调 ...

  5. 设计模式之Birdge(桥接)模式

    1.出现原因 1.同一个类型,有两个变化的维度(两个维度的抽象:一个抽象部分的抽象,一个实现部分的抽象) 2.如何应对这种“多维度的变化”?如何利用面向对象技术来使得同一类型可以轻松地沿着两个方向变化 ...

  6. 团队作业index

    <head><meta http-equiv="Content-Type" content="text/html; charset=gb2312&quo ...

  7. 点亮led【转载】

    http://linux-sunxi.org/Cubieboard/Programming/StatusLEDs Accessing the status LEDs The Cubieboard ha ...

  8. 如何教你在NIPS会议上批量下载历年的pdf文档(另附04~14年NIPS论文下载链接)

    如何获得NIPS会议上批量下载的链接? NIPS会议下载网址:http://papers.nips.cc/ a.点击打开上述网站,进入某一年的所有会议,例如2014年,如下图 b.然后对着当前网页点击 ...

  9. CSS3图片旋转特效

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  10. 增强学习————K-摇臂赌博机

    探索与利用增强学习任务的最终奖赏是在多步动作之后才能观察到,于是我们先考虑最简单的情形:最大化单步奖赏,即仅考虑一步操作.不过,就算这样,强化学习仍与监督学习有显著不同,因为机器要通过尝试来发现各个动 ...