面相对象 (继承封装多态 / ECMA6类)

什么是面向对象

面向对象是一种编程思想,我们要通过类和对象的语法,实现面向对象编程。
使用面向对象思想编程后,具有继承、封装、多态的特点。

还是讲到了构造函数
来看代码

			//创建人的构造函数
			function Person(name, sex){
				this.name = name;
				this.sex = sex;
			}
			Person.prototype.showName = function(){
				alert("我叫" + this.name);
			}
			Person.prototype.showSex = function(){
				alert("我是" + this.sex + '的');
			}
			
			// 创建一个白领类  继承Person所有属性和方法
			function Worker(name, sex, job){
				//继承属性  构造函数的伪装
				Person.call(this, name, sex);//在这里继承到了Person的属性
				this.job = job;
			}
			
			//继承方法  原型链
			for(var i in Person.prototype){//通过for in去遍历数组
				Worker.prototype[i] = Person.prototype[i];//给Woeler添加Person的内容
			}
			Worker.prototype.showJob = function(){//给Woeler添加showJob方法
				alert("我是做" + this.job + "的");
			}

			//最后输出下结果
			var w1 = new Worker("blue", '男', "程序员");
			w1.showName();
			w1.showSex();
			w1.showJob();

			var p1 = new Person("red", '女');
			p1.showName();
			p1.showSex();
			alert(p1.showJob);

这里有个问题是对象是引用数据类型
引用数据类型的问题是我们拿到的是地址,实际数据存储在数据存储端。
直接改数据会有问题。

			var obj1 = {
				a: 10,
				b: 20,
				c: 30
			}
			var obj2 = obj1;
			obj2.d = 40;
			console.log(obj1);

上面的输出结果两个都被改了

			var obj1 = {
				a: 10,
				b: 20,
				c: 30
			}
			var obj2 = {};
			for(var i in obj1){
				obj2[i] = obj1[i];
			}
			obj2.d = 40;
			console.log(obj1);

但这个样子吧数据一个一个附进去
obj1就没有改变,依然是10.20.30

现在我们谈一谈多态

	如果子一级构造函数,重写父一级继承下来的方法,这个方法只在子一级生效,父一级不受影响的。

	同一件事情两个侧重:
			继承:更加侧重于,从父级继承下来的属性和方法。
			多态:更加侧重于,在子级拓展或重写的属性和方法。
			function Father(name, sex){
				this.name = name;
				this.sex = sex;
			}

			Father.prototype.run = function(){//通过prototype给Father添加run
				alert("跑的特别快,年轻的时候做过邮递员");
			}

			function Son(name, sex){//下面的三种方法皆可以给Son继承Father的元素
				// Father.call(this, name, sex);
				Father.apply(this, [name, sex]);
				// Father.bind(this)(name, sex);
			}

			//原型链
			for(var i in Father.prototype){
				Son.prototype[i] = Father.prototype[i];
			}

			//重写父一级继承的方法
			Son.prototype.run = function(){//多态,重写
				alert("很能跑,去了田径队,拿了全国冠军");
			}
			var s1 = new Son("小明", '男');
			s1.run();//很能跑,去了田径队,拿了全国冠军
			var f1 = new Father("大明", '男');
			f1.run();//跑的特别快,年轻的时候做过邮递员

ECMA6类

还有新的问题
上篇文章说到ECMA6之前我们一直用上述方法去做类
那么ECMA6出了类我们应该怎么做呢

先之前的代码

			//声明
			function Iphone(color, size){
				this.color = color;
				this.size = size;
			}
			//添加show
			Iphone.prototype.show = function(){
				alert(`你选择了${this.color}颜色的,存储大小为${this.size}GB Iphone手机`);
			}
			//new
			var iphone8 = new Iphone("玫瑰金", 128);
			iphone8.show();

ECMA6 类的语法

			//声明
			class Iphone{//class
				constructor(color, size){//constructor元素
					this.color = color;
					this.size = size;
				}
				
				show(){//方法
					alert(`你选择了${this.color}颜色的,存储大小为${this.size}GB Iphone手机`);
				}
			}

			var iphone8 = new Iphone("玫瑰金", 128);
			iphone8.show();

看起来确实是煎蛋了不少,但明显的兼容问题。
那么我们继续说继承的问题

			class Iphone{
				constructor(color, size){
					this.color = color;
					this.size = size;
				}

				show(){
					alert(`你选择了${this.color}颜色的,存储大小为${this.size}GB Iphone手机`);
				}
			}

			class IphoneX extends Iphone{//IphoneX继承Iphone
				constructor(color, size, type){
					super(color, size);
					this.type = type;
				}
				showSelf(){
					alert(`我选择是是${this.type}的手机`);
					this.show();
				}
			}

			var iphone8 = new Iphone("玫瑰金", 128);
			iphone8.show();//你选择了玫瑰金颜色的,存储大小为128GB Iphone手机

			var iphoneXsMax = new IphoneX("黑色", 256, "xsMax");
			iphoneXsMax.showSelf();//我选择是是xsMax的手机//你选择了黑色颜色的,存储大小为256GB Iphone手机

还有关于这套代码有很多细节拓展知识,进阶看这里,注释有详细解释:

三个继承方法
_ _ proto _ _(注意两边是两个杠,但因为这个浏览器编辑器里两个杠是标签,所以我加了空格。)

			//创建人的构造函数
			function Person(name, sex){
				this.name = name;
				this.sex = sex;
			}

			Person.prototype.showName = function(){
				alert("我叫" + this.name);
			}
			Person.prototype.showSex = function(){
				alert("我是" + this.sex + '的');
			}

			// 创建一个白领类  继承Person所有属性和方法
			function Worker(name, sex, job){
				//继承属性  构造函数的伪装
				Person.call(this, name, sex);
				this.job = job;
			}

			//三种继承的地方法 (原型链/new/Object.create)
			//1、继承方法  原型链
			//for(var i in Person.prototype){
			//	Worker.prototype[i] = Person.prototype[i];
			//}
			//2、直接通过调用构造函数继承
			// Worker.prototype = new Person();
			//3、通过Object.create继承
			Worker.prototype = Object.create(Person.prototype);

			Worker.prototype.showJob = function(){
				alert("我是做" + this.job + "的");
			}

			//	【注】通过构造函数,构造出来的对象,有一个叫做__proto__的属性。
			//	这个属性,指向,构造出来这个对象的构造函数的prototype。
			
			var w1 = new Worker("blue", '男', "程序员");
			/*w1.showName();
			w1.showSex();
			w1.showJob();*/

			alert(w1.__proto__.showJob === Worker.prototype.showJob);

			var p1 = new Person("red", '女');
			/*p1.showName();
			p1.showSex();
			alert(p1.showJob);*/

			alert(w1.__proto__ === p1.__proto__);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值