Javascript基于对象三大特征

Javascript基于对象三大特征

基本概述

    Javascript基于对象的三大特征和C++,Java面向对象的三大特征一样,都是封装(encapsulation)、继承(inheritance )和多态(polymorphism )。只不过实现的方式不同,其基本概念是差不多的。其实除三大特征之外,还有一个常见的特征叫做抽象(abstract),这也就是我们在一些书上有时候会看到面向对象四大特征的原因了。

 

封装性

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

 

案例:

<html>
	<head>
		<script type="text/javascript">
			function Person(name, agei, sal){
				// 公开
				this.name = name;
				// 私有
				var age = agei;
				var salary = sal;
			}
			var p1 = new Person('zs', 20, 10000);
			window.alert(p1.name + p1.age);
		</script>
	</head>
	<body>
	</body>
</html>

PS:JS封装只有两种状态,一种是公开的,一种是私有的。


通过构造函数添加成员方法和通过原型法添加成员方法的区别

1、通过原型法分配的函数是所有对象共享的.

2、通过原型法分配的属性是独立.(如果你不修改属性,他们是共享)

3、建议,如果我们希望所有的对象使用同一一个函数,最好使用原型法添加函数,这样比较节省内存.

 

案例:

function Person(){

    this.name="zs";

    var age=20;

    this.abc=function(){

        window.alert("abc");

    }

    function abc2(){

        window.alert("abc");

    }

}

Person.prototype.fun1=function(){

    window.alert(this.name);//ok

    //window.alert(age);//no ok

    //abc2();//no ok

    this.abc();//ok

}

var p1=new Person();

p1.fun1();


特别强调:我们前面学习的通过prototype给所有的对象添加方法,但是这种方式不能去访问类的私有变量和方法。


继承性

    继承可以解决代码复用,让编程更加靠近人类思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过继承父类中的属性和方法。

 

JS中实现继承的方式

1、对象冒充

案例:

<html>
	<head>
		<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) {
				this.stu = Stu;
				// 通过对象冒充来实现继承的
				// 对象冒充的意思就是获取那个类的所有成员,因为js是谁调用那个成员就是谁的,这样MidStu就有了Stu的成员了
				this.stu(name, age);
				this.payFee = function(){
					window.alert("缴费" + money * 0.8);
				}
			}
			function Pupil(name, age) {
				this.stu = Stu;
				// 通过对象冒充来实现继承的
				this.stu(name, age);
				this.payFee = function(){
					window.alert("缴费" + money * 0.5);
				}
			}

			var midStu = new MidStu("zs", 13);
			midStu.show();
			var pupil = new Pupil("ls", 10);
			pupil.show();
		</script>
	</head>
	<body>
	</body>
</html>

2、通过call或者apply实现

案例:

<html>
<head>
<script type="text/javascript">
	//1. 把子类中共有的属性和方法抽取出,定义一个父类Stu
	function Stu(name,age){
		// window.alert("确实被调用.");
		this.name=name;
		this.age=age;
		this.show=function(){
			window.alert(this.name+"年龄是="+this.age);
		}
	}
	//2.通过对象冒充来继承父类的属性的方法
	function MidStu(name,age){
		//这里这样理解: 通过call修改了Stu构造函数的this指向,
		//让它指向了调用者本身.
		Stu.call(this,name,age);
		//如果用apply实现,则可以
        //Stu.apply(this,[name,age]); //说明传入的参数是 数组方式
		//可以写MidStu自己的方法.
		this.pay=function(fee){
			window.alert("你的学费是"+fee*0.8);
		}
	}
	function Pupil(name,age){
		Stu.call(this,name,age);//当我们创建Pupil对象实例,Stu的构造函数会被执行,当执行后,我们Pupil对象就获取从 Stu封装的属性和方法
		//可以写Pupil自己的方法.
		this.pay=function(fee){
			window.alert("你的学费是"+fee*0.5);
		}
	}
	//测试
	var midstu=new MidStu("zs",15);
	var pupil=new Pupil("ls",12);
	midstu.show();
	midstu.pay(100);
	pupil.show();
	pupil.pay(100);
</script>
</html>

小结:

1JS对象可以通过对象冒充,实现多重继承

2Object类是所有Js类的基类


多态性

JS的函数重载

    这个是多态的基础,在之前的Javascript入门已经说过了,JS函数不支持多态,但是事实上JS函数是无态的,支持任意长度,类型的参数列表。如果同时定义了多个同名函数,则以最后一个函数为准。

 

案例:

<html>
<head>
<script type="text/javascript">
	//*****************说明js不支持重载*****
	/*function Person(){
		this.test1=function (a,b){
			window.alert('function (a,b)');	
		}
		this.test1=function (a){
			window.alert('function (a)');
		}
	}
	var p1=new Person();
	//js中不支持重载.
    //但是这不会报错,js会默认是最后同名一个函数,可以看做是后面的把前面的覆盖了。
	p1.test1("a","b");
	p1.test1("a");*/
	
	//js怎么实现重载.通过判断参数的个数来实现重载
	function Person(){
		this.test1=function (){
			if(arguments.length==1){
				this.show1(arguments[0]);
			}else if(arguments.length==2){
				this.show2(arguments[0],arguments[1]);
			}else if(arguments.length==3){
				this.show3(arguments[0],arguments[1],arguments[2]);
			}
		}
		this.show1=function(a){
			window.alert("show1()被调用"+a);
		}
		this.show2=function(a,b){
			window.alert("show2()被调用"+"--"+a+"--"+b);
		}
		function show3(a,b,c){
			window.alert("show3()被调用");
		}
	}
	var p1=new Person();
	//js中不支持重载.
	p1.test1("a","b");
	p1.test1("a");
</script>
</html>

多态基本概念

    多态是指一个引用(类型)在不同情况下的多种状态。也可以理解成:多态是指通过指向父类的引用,来调用在不同子类中实现的方法。

 

案例:

<script type="text/javascript">
	// Master类
	function Master(name){
		this.nam=name;
		//方法[给动物喂食物]
	}
	//原型法添加成员函数
	Master.prototype.feed=function (animal,food){
		window.alert("给"+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 Peach(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 fish=new Fish("鱼");

	var dog=new Dog("狗");
	var bone=new Bone("骨头");

	var monkey=new Monkey("猴");
	var peach=new Peach("桃");

	//创建一个主人
	var master=new Master("zs");
	master.feed(dog,bone);
    master.feed(cat,fish);
    master.feed(monkey,peach);
</script>

总结:

   多态利于代码的维护和扩展,当我们需要使用同一类树上的对象时,只需要传入不同的参数就行了,而不需要再new 一个对象。



----------参考《韩顺平.轻松搞定网页设计(html+css+js)》


你可能感兴趣的:(面向对象,面向对象三大特征,javascript.基于对象)